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

feature: Renderer Framebuffer type #1637

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ encoding_rs = { version = "0.8.33", optional = true }
profiling = "1.0.13"
smallvec = "1.11"
pixman = { version = "0.2.1", features = ["drm-fourcc", "sync"], optional = true }
aliasable = { version = "0.1.3", optional = true }


[dev-dependencies]
Expand Down Expand Up @@ -99,7 +100,7 @@ backend_session_libseat = ["backend_session", "libseat"]
desktop = []
renderer_gl = ["gl_generator", "backend_egl"]
renderer_glow = ["renderer_gl", "glow"]
renderer_multi = ["backend_drm"]
renderer_multi = ["backend_drm", "aliasable"]
renderer_pixman = ["pixman"]
renderer_test = []
use_system_lib = ["wayland_frontend", "wayland-backend/server_system", "wayland-sys", "gbm?/import-wayland"]
Expand Down
6 changes: 3 additions & 3 deletions anvil/src/drawing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,14 @@ where
}

#[cfg(feature = "debug")]
impl<R> RenderElement<R> for FpsElement<<R as Renderer>::TextureId>
impl<R> RenderElement<R> for FpsElement<R::TextureId>
where
R: Renderer + ImportAll,
<R as Renderer>::TextureId: 'static,
R::TextureId: 'static,
{
fn draw(
&self,
frame: &mut <R as Renderer>::Frame<'_>,
frame: &mut R::Frame<'_, '_>,
_src: Rectangle<f64, Buffer>,
dst: Rectangle<i32, Physical>,
damage: &[Rectangle<i32, Physical>],
Expand Down
5 changes: 3 additions & 2 deletions anvil/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ smithay::backend::renderer::element::render_elements! {
// a feature-dependent lifetime, which introduces a lot more feature bounds
// as the whole type changes and we can't have an unused lifetime (for when "debug" is disabled)
// in the declaration.
Fps=FpsElement<<R as Renderer>::TextureId>,
Fps=FpsElement<R::TextureId>,
}

impl<R: Renderer> std::fmt::Debug for CustomRenderElements<R> {
Expand Down Expand Up @@ -195,6 +195,7 @@ pub fn render_output<'a, 'd, R>(
space: &'a Space<WindowElement>,
custom_elements: impl IntoIterator<Item = CustomRenderElements<R>>,
renderer: &'a mut R,
framebuffer: &'a mut R::Framebuffer<'_>,
damage_tracker: &'d mut OutputDamageTracker,
age: usize,
show_window_preview: bool,
Expand All @@ -205,5 +206,5 @@ where
{
let (elements, clear_color) =
output_elements(output, space, custom_elements, renderer, show_window_preview);
damage_tracker.render_output(renderer, age, &elements, clear_color)
damage_tracker.render_output(renderer, framebuffer, age, &elements, clear_color)
}
2 changes: 1 addition & 1 deletion anvil/src/shell/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ impl<R: Renderer> std::fmt::Debug for WindowRenderElement<R> {
impl<R> AsRenderElements<R> for WindowElement
where
R: Renderer + ImportAll + ImportMem,
<R as Renderer>::TextureId: Clone + Texture + 'static,
R::TextureId: Clone + Texture + 'static,
{
type RenderElement = WindowRenderElement<R>;

Expand Down
2 changes: 1 addition & 1 deletion anvil/src/udev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1354,7 +1354,7 @@ impl AnvilState<UdevData> {
!has_rendered
}
Err(err) => {
warn!("Error during rendering: {:?}", err);
warn!("Error during rendering: {:#?}", err);
match err {
SwapBuffersError::AlreadySwapped => false,
SwapBuffersError::TemporaryFailure(err) => match err.downcast_ref::<DrmError>() {
Expand Down
49 changes: 25 additions & 24 deletions anvil/src/winit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,31 +291,29 @@ pub fn run_winit() {

#[cfg(feature = "debug")]
let mut renderdoc = state.renderdoc.as_mut();
let render_res = backend.bind().and_then(|_| {

let age = if *full_redraw > 0 {
0
} else {
backend.buffer_age().unwrap_or(0)
};
#[cfg(feature = "debug")]
let window_handle = backend
.window()
.window_handle()
.map(|handle| {
if let RawWindowHandle::Wayland(handle) = handle.as_raw() {
handle.surface.as_ptr()
} else {
std::ptr::null_mut()
}
})
.unwrap_or_else(|_| std::ptr::null_mut());
let render_res = backend.bind().and_then(|(renderer, mut fb)| {
#[cfg(feature = "debug")]
if let Some(renderdoc) = renderdoc.as_mut() {
renderdoc.start_frame_capture(
backend.renderer().egl_context().get_context_handle(),
backend
.window()
.window_handle()
.map(|handle| {
if let RawWindowHandle::Wayland(handle) = handle.as_raw() {
handle.surface.as_ptr()
} else {
std::ptr::null_mut()
}
})
.unwrap_or_else(|_| std::ptr::null_mut()),
);
renderdoc.start_frame_capture(renderer.egl_context().get_context_handle(), window_handle);
}
let age = if *full_redraw > 0 {
0
} else {
backend.buffer_age().unwrap_or(0)
};

let renderer = backend.renderer();

let mut elements = Vec::<CustomRenderElements<GlesRenderer>>::new();

Expand Down Expand Up @@ -349,19 +347,22 @@ pub fn run_winit() {
#[cfg(feature = "debug")]
elements.push(CustomRenderElements::Fps(fps_element.clone()));

render_output(
let res = render_output(
&output,
space,
elements,
renderer,
&mut fb,
damage_tracker,
age,
show_window_preview,
)
.map_err(|err| match err {
OutputDamageTrackerError::Rendering(err) => err.into(),
_ => unreachable!(),
})
});

res
});

match render_res {
Expand Down
16 changes: 10 additions & 6 deletions anvil/src/x11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,12 +314,15 @@ pub fn run_x11() {
#[cfg(feature = "debug")]
fps_element.update_fps(fps);

let (buffer, age) = backend_data.surface.buffer().expect("gbm device was destroyed");
if let Err(err) = backend_data.renderer.bind(buffer) {
error!("Error while binding buffer: {}", err);
profiling::finish_frame!();
continue;
}
let (mut buffer, age) = backend_data.surface.buffer().expect("gbm device was destroyed");
let mut fb = match backend_data.renderer.bind(&mut buffer) {
Ok(fb) => fb,
Err(err) => {
error!("Error while binding buffer: {}", err);
profiling::finish_frame!();
continue;
}
};

#[cfg(feature = "debug")]
if let Some(renderdoc) = state.renderdoc.as_mut() {
Expand Down Expand Up @@ -394,6 +397,7 @@ pub fn run_x11() {
&state.space,
elements,
&mut backend_data.renderer,
&mut fb,
&mut backend_data.damage_tracker,
age.into(),
state.show_window_preview,
Expand Down
29 changes: 15 additions & 14 deletions examples/buffer_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ fn buffer_test(args: TestArgs) {
};

// 2. alloc buffer
let buffer = allocator
let mut buffer = allocator
.create_buffer(args.width, args.height, args.fourcc, &[args.modifier])
.expect("Failed to allocate buffer");

Expand All @@ -223,12 +223,7 @@ fn buffer_test(args: TestArgs) {
let context = EGLContext::new(&display).expect("Failed to create EGL context");
let mut renderer = unsafe { GlesRenderer::new(context).expect("Failed to init GL ES renderer") };

render_into(
&mut renderer,
buffer.clone(),
args.width as i32,
args.height as i32,
);
render_into(&mut renderer, &mut buffer, args.width as i32, args.height as i32);
}
}

Expand Down Expand Up @@ -274,15 +269,15 @@ fn buffer_test(args: TestArgs) {
}
}

fn render_into<R, T>(renderer: &mut R, buffer: T, w: i32, h: i32)
fn render_into<R, T>(renderer: &mut R, buffer: &mut T, w: i32, h: i32)
where
R: Renderer + Bind<T>,
{
// Bind it as a framebuffer
renderer.bind(buffer).expect("Failed to bind dmabuf");
let mut framebuffer = renderer.bind(buffer).expect("Failed to bind dmabuf");

let mut frame = renderer
.render((w, h).into(), Transform::Normal)
.render(&mut framebuffer, (w, h).into(), Transform::Normal)
.expect("Failed to create render frame");
frame
.clear(
Expand Down Expand Up @@ -322,11 +317,13 @@ where
let texture = renderer
.import_dmabuf(&buffer, None)
.expect("Failed to import dmabuf");
let offscreen = Offscreen::<T>::create_buffer(renderer, Fourcc::Abgr8888, (w, h).into())
let mut offscreen = Offscreen::<T>::create_buffer(renderer, Fourcc::Abgr8888, (w, h).into())
.expect("Failed to create offscreen buffer");
renderer.bind(offscreen).expect("Failed to bind offscreen buffer");
let mut framebuffer = renderer
.bind(&mut offscreen)
.expect("Failed to bind offscreen buffer");
let mut frame = renderer
.render((w, h).into(), Transform::Normal)
.render(&mut framebuffer, (w, h).into(), Transform::Normal)
.expect("Failed to create render frame");
frame
.render_texture_at(
Expand All @@ -348,7 +345,11 @@ where

if let Some(path) = dump {
let mapping = renderer
.copy_framebuffer(Rectangle::from_size((w, h).into()), Fourcc::Abgr8888)
.copy_framebuffer(
&framebuffer,
Rectangle::from_size((w, h).into()),
Fourcc::Abgr8888,
)
.expect("Failed to map framebuffer");
let copy = renderer.map_texture(&mapping).expect("Failed to read mapping");
image::save_buffer(path, copy, w as u32, h as u32, image::ColorType::Rgba8)
Expand Down
76 changes: 39 additions & 37 deletions examples/minimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,49 +205,51 @@ pub fn run_winit() -> Result<(), Box<dyn std::error::Error>> {
PumpStatus::Exit(_) => return Ok(()),
};

backend.bind().unwrap();

let size = backend.window_size();
let damage = Rectangle::from_size(size);
{
let (renderer, mut framebuffer) = backend.bind().unwrap();
let elements = state
.xdg_shell_state
.toplevel_surfaces()
.iter()
.flat_map(|surface| {
render_elements_from_surface_tree(
renderer,
surface.wl_surface(),
(0, 0),
1.0,
1.0,
Kind::Unspecified,
)
})
.collect::<Vec<WaylandSurfaceRenderElement<GlesRenderer>>>();

let mut frame = renderer
.render(&mut framebuffer, size, Transform::Flipped180)
.unwrap();
frame.clear(Color32F::new(0.1, 0.0, 0.0, 1.0), &[damage]).unwrap();
draw_render_elements(&mut frame, 1.0, &elements, &[damage]).unwrap();
// We rely on the nested compositor to do the sync for us
let _ = frame.finish().unwrap();

let elements = state
.xdg_shell_state
.toplevel_surfaces()
.iter()
.flat_map(|surface| {
render_elements_from_surface_tree(
backend.renderer(),
surface.wl_surface(),
(0, 0),
1.0,
1.0,
Kind::Unspecified,
)
})
.collect::<Vec<WaylandSurfaceRenderElement<GlesRenderer>>>();

let mut frame = backend.renderer().render(size, Transform::Flipped180).unwrap();
frame.clear(Color32F::new(0.1, 0.0, 0.0, 1.0), &[damage]).unwrap();
draw_render_elements(&mut frame, 1.0, &elements, &[damage]).unwrap();
// We rely on the nested compositor to do the sync for us
let _ = frame.finish().unwrap();

for surface in state.xdg_shell_state.toplevel_surfaces() {
send_frames_surface_tree(surface.wl_surface(), start_time.elapsed().as_millis() as u32);
}
for surface in state.xdg_shell_state.toplevel_surfaces() {
send_frames_surface_tree(surface.wl_surface(), start_time.elapsed().as_millis() as u32);
}

if let Some(stream) = listener.accept()? {
println!("Got a client: {:?}", stream);
if let Some(stream) = listener.accept()? {
println!("Got a client: {:?}", stream);

let client = display
.handle()
.insert_client(stream, Arc::new(ClientState::default()))
.unwrap();
clients.push(client);
}
let client = display
.handle()
.insert_client(stream, Arc::new(ClientState::default()))
.unwrap();
clients.push(client);
}

display.dispatch_clients(&mut state)?;
display.flush_clients()?;
display.dispatch_clients(&mut state)?;
display.flush_clients()?;
}

// It is important that all events on the display have been dispatched and flushed to clients before
// swapping buffers because this operation may block.
Expand Down
32 changes: 20 additions & 12 deletions smallvil/src/winit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,26 @@ pub fn init_winit(
let size = backend.window_size();
let damage = Rectangle::from_size(size);

backend.bind().unwrap();
smithay::desktop::space::render_output::<_, WaylandSurfaceRenderElement<GlesRenderer>, _, _>(
&output,
backend.renderer(),
1.0,
0,
[&state.space],
&[],
&mut damage_tracker,
[0.1, 0.1, 0.1, 1.0],
)
.unwrap();
{
let (renderer, mut framebuffer) = backend.bind().unwrap();
smithay::desktop::space::render_output::<
_,
WaylandSurfaceRenderElement<GlesRenderer>,
_,
_,
>(
&output,
renderer,
&mut framebuffer,
1.0,
0,
[&state.space],
&[],
&mut damage_tracker,
[0.1, 0.1, 0.1, 1.0],
)
.unwrap();
}
backend.submit(Some(&[damage])).unwrap();

state.space.elements().for_each(|window| {
Expand Down
Loading
Loading