Skip to content

Commit

Permalink
LinuxKMS: Add support for partial rendering with the Slint software r…
Browse files Browse the repository at this point in the history
…enderer
  • Loading branch information
tronical committed Jun 10, 2024
1 parent ab82ece commit 1b95249
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 6 deletions.
14 changes: 12 additions & 2 deletions internal/backends/linuxkms/display/swdisplay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ impl SoftwareBufferDisplay {
&self,
callback: &mut dyn FnMut(
drm::control::dumbbuffer::DumbMapping<'_>,
u8,
) -> Result<(), PlatformError>,
) -> Result<(), PlatformError> {
let mut back_buffer = self.back_buffer.borrow_mut();
let age = back_buffer.age;
self.drm_output
.drm_device
.map_dumb_buffer(&mut back_buffer.buffer_handle)
.map_err(|e| PlatformError::Other(format!("Error mapping dumb buffer: {e}").into()))
.and_then(callback)
.and_then(|buffer| callback(buffer, age))
}
}

Expand All @@ -52,6 +54,13 @@ impl super::Presenter for SoftwareBufferDisplay {
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// TODO: dirty framebuffer
self.front_buffer.swap(&self.back_buffer);
self.front_buffer.borrow_mut().age = 1;
{
let mut back_buffer = self.back_buffer.borrow_mut();
if back_buffer.age != 0 {
back_buffer.age += 1;
}
}
self.drm_output.present(
self.front_buffer.borrow().buffer_handle,
self.front_buffer.borrow().fb_handle,
Expand All @@ -68,6 +77,7 @@ impl super::Presenter for SoftwareBufferDisplay {
struct DumbBuffer {
fb_handle: drm::control::framebuffer::Handle,
buffer_handle: drm::control::dumbbuffer::DumbBuffer,
age: u8,
}

impl DumbBuffer {
Expand All @@ -82,6 +92,6 @@ impl DumbBuffer {
.add_framebuffer(&buffer_handle, 24, 32)
.map_err(|e| format!("Error creating framebuffer for dumb buffer: {e}"))?;

Ok(Self { fb_handle, buffer_handle })
Ok(Self { fb_handle, buffer_handle, age: 0 })
}
}
9 changes: 8 additions & 1 deletion internal/backends/linuxkms/fullscreenwindowadapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ use std::pin::Pin;
use std::rc::Rc;

use i_slint_core::api::{LogicalPosition, PhysicalSize as PhysicalWindowSize};
use i_slint_core::graphics::Image;
use i_slint_core::graphics::{euclid, Image};
use i_slint_core::item_rendering::ItemRenderer;
use i_slint_core::lengths::LogicalRect;
use i_slint_core::platform::WindowEvent;
use i_slint_core::slice::Slice;
use i_slint_core::Property;
Expand Down Expand Up @@ -108,13 +109,19 @@ impl FullscreenWindowAdapter {
self.rotation,
&|item_renderer| {
if let Some(mouse_position) = mouse_position.get() {
let cursor_image = mouse_cursor_image();
item_renderer.save_state();
item_renderer.translate(
i_slint_core::lengths::logical_point_from_api(mouse_position)
.to_vector(),
);
item_renderer.draw_image_direct(mouse_cursor_image());
item_renderer.restore_state();
let cursor_rect = LogicalRect::new(
euclid::point2(mouse_position.x, mouse_position.y),
euclid::Size2D::from_untyped(cursor_image.size().cast()),
);
self.renderer.as_core_renderer().mark_dirty_region(cursor_rect.into());
}
},
Box::new({
Expand Down
2 changes: 1 addition & 1 deletion internal/backends/linuxkms/renderer/skia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ impl i_slint_renderer_skia::software_surface::RenderBuffer for DrmDumbBufferAcce
return Ok(());
};

self.display.map_back_buffer(&mut |mut pixels| {
self.display.map_back_buffer(&mut |mut pixels, _age| {
render_callback(width, height, skia_safe::ColorType::BGRA8888, pixels.as_mut())
})
}
Expand Down
10 changes: 8 additions & 2 deletions internal/backends/linuxkms/renderer/sw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use i_slint_core::api::PhysicalSize as PhysicalWindowSize;
use i_slint_core::platform::PlatformError;
pub use i_slint_core::software_renderer::SoftwareRenderer;
use i_slint_core::software_renderer::{PremultipliedRgbaColor, TargetPixel};
use i_slint_core::software_renderer::{PremultipliedRgbaColor, RepaintBufferType, TargetPixel};
use std::rc::Rc;

use crate::display::{Presenter, RenderingRotation};
Expand Down Expand Up @@ -96,7 +96,13 @@ impl crate::fullscreenwindowadapter::FullscreenRenderer for SoftwareRendererAdap
_draw_mouse_cursor_callback: &dyn Fn(&mut dyn i_slint_core::item_rendering::ItemRenderer),
ready_for_next_animation_frame: Box<dyn FnOnce()>,
) -> Result<(), PlatformError> {
self.display.map_back_buffer(&mut |mut pixels| {
self.display.map_back_buffer(&mut |mut pixels, age| {
self.renderer.set_repaint_buffer_type(match age {
1 => RepaintBufferType::ReusedBuffer,
2 => RepaintBufferType::SwappedBuffers,
_ => RepaintBufferType::NewBuffer,
});

self.renderer.set_rendering_rotation(match rotation {
RenderingRotation::NoRotation => {
i_slint_core::software_renderer::RenderingRotation::NoRotation
Expand Down

0 comments on commit 1b95249

Please sign in to comment.