mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-01 20:31:27 +00:00
WIP: Start wrapping TargetPIxelBuffer in C++
This commit is contained in:
parent
543ed39058
commit
fbee7f9566
3 changed files with 228 additions and 2 deletions
|
|
@ -46,7 +46,7 @@ system-testing = ["i-slint-backend-selector/system-testing"]
|
|||
|
||||
std = ["i-slint-core/default", "i-slint-core/image-default-formats", "i-slint-backend-selector"]
|
||||
freestanding = ["i-slint-core/libm", "i-slint-core/unsafe-single-threaded"]
|
||||
experimental = []
|
||||
experimental = ["i-slint-core/experimental"]
|
||||
|
||||
default = ["std", "backend-winit", "renderer-femtovg", "backend-qt"]
|
||||
|
||||
|
|
|
|||
|
|
@ -538,6 +538,20 @@ struct Rgb565Pixel
|
|||
friend bool operator==(const Rgb565Pixel &lhs, const Rgb565Pixel &rhs) = default;
|
||||
};
|
||||
|
||||
# ifdef SLINT_FEATURE_EXPERIMENTAL
|
||||
template<typename PixelType>
|
||||
struct TargetPixelBuffer
|
||||
{
|
||||
virtual ~TargetPixelBuffer() { }
|
||||
|
||||
virtual std::span<PixelType> line_slice(std::size_t line_number) = 0;
|
||||
virtual std::size_t num_lines() = 0;
|
||||
|
||||
virtual bool fill_rectangle(int16_t x, int16_t y, int16_t width, int16_t height,
|
||||
const RgbaColor<uint8_t> &premultiplied_color) = 0;
|
||||
};
|
||||
# endif
|
||||
|
||||
/// Slint's software renderer.
|
||||
///
|
||||
/// To be used as a template parameter of the WindowAdapter.
|
||||
|
|
@ -680,6 +694,69 @@ public:
|
|||
return PhysicalRegion { r };
|
||||
}
|
||||
|
||||
# ifdef SLINT_FEATURE_EXPERIMENTAL
|
||||
PhysicalRegion render(TargetPixelBuffer<Rgb8Pixel> *buffer) const
|
||||
{
|
||||
cbindgen_private::CppRgb8TargetPixelBuffer buffer_wrapper {
|
||||
.user_data = buffer,
|
||||
.line_slice =
|
||||
[](void *self, uintptr_t line_number, Rgb8Pixel **slice_ptr,
|
||||
uintptr_t *slice_len) {
|
||||
auto *buffer = reinterpret_cast<TargetPixelBuffer<Rgb8Pixel> *>(self);
|
||||
auto slice = buffer->line_slice(line_number);
|
||||
*slice_ptr = slice.data();
|
||||
*slice_len = slice.size();
|
||||
},
|
||||
.num_lines =
|
||||
[](void *self) {
|
||||
auto *buffer = reinterpret_cast<TargetPixelBuffer<Rgb8Pixel> *>(self);
|
||||
return buffer->num_lines();
|
||||
},
|
||||
.fill_rectangle =
|
||||
[](void *self, int16_t x, int16_t y, int16_t width, int16_t height, uint8_t red,
|
||||
uint8_t green, uint8_t blue, uint8_t alpha) {
|
||||
auto *buffer = reinterpret_cast<TargetPixelBuffer<Rgb8Pixel> *>(self);
|
||||
return buffer->fill_rectangle(
|
||||
x, y, width, height,
|
||||
Color::from_argb_uint8(alpha, red, green, blue));
|
||||
}
|
||||
};
|
||||
auto r =
|
||||
cbindgen_private::slint_software_renderer_render_accel_rgb8(inner, &buffer_wrapper);
|
||||
return PhysicalRegion { r };
|
||||
}
|
||||
PhysicalRegion render(TargetPixelBuffer<Rgb565Pixel> *buffer) const
|
||||
{
|
||||
cbindgen_private::CppRgb565TargetPixelBuffer buffer_wrapper {
|
||||
.user_data = buffer,
|
||||
.line_slice =
|
||||
[](void *self, uintptr_t line_number, uint16_t **slice_ptr,
|
||||
uintptr_t *slice_len) {
|
||||
auto *buffer = reinterpret_cast<TargetPixelBuffer<Rgb565Pixel> *>(self);
|
||||
auto slice = buffer->line_slice(line_number);
|
||||
*slice_ptr = reinterpret_cast<uint16_t *>(slice.data());
|
||||
*slice_len = slice.size();
|
||||
},
|
||||
.num_lines =
|
||||
[](void *self) {
|
||||
auto *buffer = reinterpret_cast<TargetPixelBuffer<Rgb565Pixel> *>(self);
|
||||
return buffer->num_lines();
|
||||
},
|
||||
.fill_rectangle =
|
||||
[](void *self, int16_t x, int16_t y, int16_t width, int16_t height, uint8_t red,
|
||||
uint8_t green, uint8_t blue, uint8_t alpha) {
|
||||
auto *buffer = reinterpret_cast<TargetPixelBuffer<Rgb565Pixel> *>(self);
|
||||
return buffer->fill_rectangle(
|
||||
x, y, width, height,
|
||||
Color::from_argb_uint8(alpha, red, green, blue));
|
||||
}
|
||||
};
|
||||
auto r = cbindgen_private::slint_software_renderer_render_accel_rgb565(inner,
|
||||
&buffer_wrapper);
|
||||
return PhysicalRegion { r };
|
||||
}
|
||||
# endif
|
||||
|
||||
/// Render the window scene into an RGB 565 encoded pixel buffer
|
||||
///
|
||||
/// The buffer must be at least as large as the associated slint::Window
|
||||
|
|
|
|||
|
|
@ -356,10 +356,139 @@ mod software_renderer {
|
|||
type SoftwareRendererOpaque = *const c_void;
|
||||
use i_slint_core::graphics::{IntRect, Rgb8Pixel};
|
||||
use i_slint_core::software_renderer::{
|
||||
PhysicalRegion, RepaintBufferType, Rgb565Pixel, SoftwareRenderer,
|
||||
PhysicalRegion, PremultipliedRgbaColor, RepaintBufferType, Rgb565Pixel, SoftwareRenderer,
|
||||
TargetPixelBuffer,
|
||||
};
|
||||
use i_slint_core::SharedVector;
|
||||
|
||||
type CppTargetPixelBufferUserData = *mut c_void;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CppRgb8TargetPixelBuffer {
|
||||
user_data: CppTargetPixelBufferUserData,
|
||||
line_slice: unsafe extern "C" fn(
|
||||
CppTargetPixelBufferUserData,
|
||||
usize,
|
||||
slice_ptr: &mut *mut Rgb8Pixel,
|
||||
slice_len: *mut usize,
|
||||
),
|
||||
num_lines: unsafe extern "C" fn(CppTargetPixelBufferUserData) -> usize,
|
||||
fill_rectangle: unsafe extern "C" fn(
|
||||
CppTargetPixelBufferUserData,
|
||||
i16,
|
||||
i16,
|
||||
i16,
|
||||
i16,
|
||||
u8,
|
||||
u8,
|
||||
u8,
|
||||
u8,
|
||||
) -> bool,
|
||||
}
|
||||
|
||||
impl TargetPixelBuffer for CppRgb8TargetPixelBuffer {
|
||||
type Pixel = Rgb8Pixel;
|
||||
|
||||
fn line_slice(&mut self, line_number: usize) -> &mut [Self::Pixel] {
|
||||
unsafe {
|
||||
let mut data = core::ptr::null_mut();
|
||||
let mut len = 0;
|
||||
(self.line_slice)(self.user_data, line_number, &mut data, &mut len);
|
||||
core::slice::from_raw_parts_mut(data, len)
|
||||
}
|
||||
}
|
||||
|
||||
fn num_lines(&self) -> usize {
|
||||
unsafe { (self.num_lines)(self.user_data) }
|
||||
}
|
||||
|
||||
fn fill_rectangle(
|
||||
&mut self,
|
||||
x: i16,
|
||||
y: i16,
|
||||
width: i16,
|
||||
height: i16,
|
||||
color: PremultipliedRgbaColor,
|
||||
) -> bool {
|
||||
unsafe {
|
||||
(self.fill_rectangle)(
|
||||
self.user_data,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
color.red,
|
||||
color.green,
|
||||
color.blue,
|
||||
color.alpha,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CppRgb565TargetPixelBuffer {
|
||||
user_data: CppTargetPixelBufferUserData,
|
||||
line_slice: unsafe extern "C" fn(
|
||||
CppTargetPixelBufferUserData,
|
||||
usize,
|
||||
slice_ptr: &mut *mut u16,
|
||||
slice_len: *mut usize,
|
||||
),
|
||||
num_lines: unsafe extern "C" fn(CppTargetPixelBufferUserData) -> usize,
|
||||
fill_rectangle: unsafe extern "C" fn(
|
||||
CppTargetPixelBufferUserData,
|
||||
i16,
|
||||
i16,
|
||||
i16,
|
||||
i16,
|
||||
u8,
|
||||
u8,
|
||||
u8,
|
||||
u8,
|
||||
) -> bool,
|
||||
}
|
||||
|
||||
impl TargetPixelBuffer for CppRgb565TargetPixelBuffer {
|
||||
type Pixel = Rgb565Pixel;
|
||||
|
||||
fn line_slice(&mut self, line_number: usize) -> &mut [Self::Pixel] {
|
||||
unsafe {
|
||||
let mut data = core::ptr::null_mut();
|
||||
let mut len = 0;
|
||||
(self.line_slice)(self.user_data, line_number, &mut data, &mut len);
|
||||
core::slice::from_raw_parts_mut(data as *mut Rgb565Pixel, len)
|
||||
}
|
||||
}
|
||||
|
||||
fn num_lines(&self) -> usize {
|
||||
unsafe { (self.num_lines)(self.user_data) }
|
||||
}
|
||||
|
||||
fn fill_rectangle(
|
||||
&mut self,
|
||||
x: i16,
|
||||
y: i16,
|
||||
width: i16,
|
||||
height: i16,
|
||||
color: PremultipliedRgbaColor,
|
||||
) -> bool {
|
||||
unsafe {
|
||||
(self.fill_rectangle)(
|
||||
self.user_data,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
color.red,
|
||||
color.green,
|
||||
color.blue,
|
||||
color.alpha,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_software_renderer_new(
|
||||
buffer_age: u32,
|
||||
|
|
@ -391,6 +520,26 @@ mod software_renderer {
|
|||
renderer.render(buffer, pixel_stride)
|
||||
}
|
||||
|
||||
#[cfg(feature = "experimental")]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_software_renderer_render_accel_rgb8(
|
||||
r: SoftwareRendererOpaque,
|
||||
buffer: *mut CppRgb8TargetPixelBuffer,
|
||||
) -> PhysicalRegion {
|
||||
let renderer = &*(r as *const SoftwareRenderer);
|
||||
unsafe { renderer.render_into_buffer(&mut *buffer) }
|
||||
}
|
||||
|
||||
#[cfg(feature = "experimental")]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_software_renderer_render_accel_rgb565(
|
||||
r: SoftwareRendererOpaque,
|
||||
buffer: *mut CppRgb565TargetPixelBuffer,
|
||||
) -> PhysicalRegion {
|
||||
let renderer = &*(r as *const SoftwareRenderer);
|
||||
unsafe { renderer.render_into_buffer(&mut *buffer) }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_software_renderer_render_rgb565(
|
||||
r: SoftwareRendererOpaque,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue