Replace the MAX_BUFFER_AGE const generic with a runtime enum

Having a const generic for that didn't turn to be a good API.
Also made the C++ side more difficult

(Also renamed buffer_stride to pixel_stride)

Closes #2135
This commit is contained in:
Olivier Goffart 2023-02-08 14:44:01 +01:00 committed by GitHub
parent 05e00fe057
commit a19efc30db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 134 additions and 148 deletions

View file

@ -194,12 +194,6 @@ public:
/// To be used as a template parameter of the WindowAdapter.
///
/// Use the render() function to render in a buffer
///
/// The MAX_BUFFER_AGE parameter specifies how many buffers are being re-used.
/// This means that the buffer passed to the render functions still contains a rendering of
/// the window that was refreshed as least that amount of frame ago.
/// It will impact how much of the screen needs to be redrawn.
template<int MAX_BUFFER_AGE = 0>
class SoftwareRenderer
{
mutable cbindgen_private::SoftwareRendererOpaque inner;
@ -208,7 +202,7 @@ public:
virtual ~SoftwareRenderer()
{
if (inner) {
cbindgen_private::slint_software_renderer_drop(MAX_BUFFER_AGE, inner);
cbindgen_private::slint_software_renderer_drop(inner);
}
};
SoftwareRenderer(const SoftwareRenderer &) = delete;
@ -216,18 +210,18 @@ public:
SoftwareRenderer() = default;
/// \private
void init(const cbindgen_private::WindowAdapterRcOpaque *win) const
void init(const cbindgen_private::WindowAdapterRcOpaque *win, int max_buffer_age) const
{
if (inner) {
cbindgen_private::slint_software_renderer_drop(MAX_BUFFER_AGE, inner);
cbindgen_private::slint_software_renderer_drop(inner);
}
inner = cbindgen_private::slint_software_renderer_new(MAX_BUFFER_AGE, win);
inner = cbindgen_private::slint_software_renderer_new(max_buffer_age, win);
}
/// \private
cbindgen_private::RendererPtr renderer_handle() const
{
return cbindgen_private::slint_software_renderer_handle(MAX_BUFFER_AGE, inner);
return cbindgen_private::slint_software_renderer_handle(inner);
}
/// Render the window scene into a pixel buffer
@ -236,10 +230,11 @@ public:
///
/// The stride is the amount of pixels between two lines in the buffer.
/// It is must be at least as large as the width of the window.
void render(std::span<slint::cbindgen_private::Rgb8Pixel> buffer, std::size_t stride) const
void render(std::span<slint::cbindgen_private::Rgb8Pixel> buffer,
std::size_t pixel_stride) const
{
cbindgen_private::slint_software_renderer_render_rgb8(MAX_BUFFER_AGE, inner, buffer.data(),
buffer.size(), stride);
cbindgen_private::slint_software_renderer_render_rgb8(inner, buffer.data(), buffer.size(),
pixel_stride);
}
};

View file

@ -6,7 +6,7 @@ use i_slint_core::api::{PhysicalSize, Window};
use i_slint_core::graphics::{IntSize, Rgb8Pixel};
use i_slint_core::platform::Platform;
use i_slint_core::renderer::Renderer;
use i_slint_core::software_renderer::SoftwareRenderer;
use i_slint_core::software_renderer::{RepaintBufferType, SoftwareRenderer};
use i_slint_core::window::ffi::WindowAdapterRcOpaque;
use i_slint_core::window::{WindowAdapter, WindowAdapterSealed};
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
@ -143,52 +143,35 @@ pub unsafe extern "C" fn slint_software_renderer_new(
) -> SoftwareRendererOpaque {
let window = core::mem::transmute::<&WindowAdapterRcOpaque, &Rc<dyn WindowAdapter>>(window);
let weak = Rc::downgrade(window);
match buffer_age {
0 => Box::into_raw(Box::new(SoftwareRenderer::<0>::new(weak))) as SoftwareRendererOpaque,
1 => Box::into_raw(Box::new(SoftwareRenderer::<1>::new(weak))) as SoftwareRendererOpaque,
2 => Box::into_raw(Box::new(SoftwareRenderer::<2>::new(weak))) as SoftwareRendererOpaque,
let repaint_buffer_type = match buffer_age {
0 => RepaintBufferType::NewBuffer,
1 => RepaintBufferType::ReusedBuffer,
2 => RepaintBufferType::SwappedBuffers,
_ => unreachable!(),
}
};
Box::into_raw(Box::new(SoftwareRenderer::new(repaint_buffer_type, weak)))
as SoftwareRendererOpaque
}
#[no_mangle]
pub unsafe extern "C" fn slint_software_renderer_drop(buffer_age: u32, r: SoftwareRendererOpaque) {
match buffer_age {
0 => drop(Box::from_raw(r as *mut SoftwareRenderer<0>)),
1 => drop(Box::from_raw(r as *mut SoftwareRenderer<1>)),
2 => drop(Box::from_raw(r as *mut SoftwareRenderer<2>)),
_ => unreachable!(),
}
pub unsafe extern "C" fn slint_software_renderer_drop(r: SoftwareRendererOpaque) {
drop(Box::from_raw(r as *mut SoftwareRenderer));
}
#[no_mangle]
pub unsafe extern "C" fn slint_software_renderer_render_rgb8(
buffer_age: u32,
r: SoftwareRendererOpaque,
buffer: *mut Rgb8Pixel,
buffer_len: usize,
buffer_stride: usize,
pixel_stride: usize,
) {
let buffer = core::slice::from_raw_parts_mut(buffer, buffer_len);
match buffer_age {
0 => (*(r as *const SoftwareRenderer<0>)).render(buffer, buffer_stride),
1 => (*(r as *const SoftwareRenderer<1>)).render(buffer, buffer_stride),
2 => (*(r as *const SoftwareRenderer<2>)).render(buffer, buffer_stride),
_ => unreachable!(),
}
(*(r as *const SoftwareRenderer)).render(buffer, pixel_stride)
}
#[no_mangle]
pub unsafe extern "C" fn slint_software_renderer_handle(
buffer_age: u32,
r: SoftwareRendererOpaque,
) -> RendererPtr {
let r = match buffer_age {
0 => (r as *const SoftwareRenderer<0>) as *const dyn Renderer,
1 => (r as *const SoftwareRenderer<1>) as *const dyn Renderer,
2 => (r as *const SoftwareRenderer<2>) as *const dyn Renderer,
_ => unreachable!(),
};
pub unsafe extern "C" fn slint_software_renderer_handle(r: SoftwareRendererOpaque) -> RendererPtr {
let r = (r as *const SoftwareRenderer) as *const dyn Renderer;
core::mem::transmute(r)
}