mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-02 04:48:27 +00:00
Add draw_texture/process_texture and use accelerated fill_rectangle for background draw
This commit is contained in:
parent
fbee7f9566
commit
3855cf6b9c
3 changed files with 214 additions and 28 deletions
|
|
@ -549,6 +549,11 @@ struct TargetPixelBuffer
|
||||||
|
|
||||||
virtual bool fill_rectangle(int16_t x, int16_t y, int16_t width, int16_t height,
|
virtual bool fill_rectangle(int16_t x, int16_t y, int16_t width, int16_t height,
|
||||||
const RgbaColor<uint8_t> &premultiplied_color) = 0;
|
const RgbaColor<uint8_t> &premultiplied_color) = 0;
|
||||||
|
virtual bool draw_texture(int16_t x, int16_t y, int16_t width, int16_t height,
|
||||||
|
const uint8_t *src, uint16_t src_stride, int16_t src_width,
|
||||||
|
int16_t src_height, uint8_t src_pixel_format, uint16_t src_dx,
|
||||||
|
uint16_t src_dy, uint16_t src_off_x, uint16_t src_off_y,
|
||||||
|
uint32_t colorize, uint8_t alpha, uint8_t rotation) = 0;
|
||||||
};
|
};
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
|
@ -719,6 +724,18 @@ public:
|
||||||
return buffer->fill_rectangle(
|
return buffer->fill_rectangle(
|
||||||
x, y, width, height,
|
x, y, width, height,
|
||||||
Color::from_argb_uint8(alpha, red, green, blue));
|
Color::from_argb_uint8(alpha, red, green, blue));
|
||||||
|
},
|
||||||
|
.draw_texture =
|
||||||
|
[](void *self, int16_t x, int16_t y, int16_t width, int16_t handle,
|
||||||
|
const uint8_t *src, uint16_t src_stride, int16_t src_width,
|
||||||
|
int16_t src_height, uint8_t src_pixel_format, uint16_t src_dx,
|
||||||
|
uint16_t src_dy, uint16_t src_off_x, uint16_t src_off_y, uint32_t colorize,
|
||||||
|
uint8_t alpha, uint8_t rotation) {
|
||||||
|
auto *buffer = reinterpret_cast<TargetPixelBuffer<Rgb8Pixel> *>(self);
|
||||||
|
return buffer->draw_texture(x, y, width, handle, src, src_stride, src_width,
|
||||||
|
src_height, src_pixel_format, src_dx, src_dy,
|
||||||
|
src_off_x, src_off_y, colorize, alpha,
|
||||||
|
rotation);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
auto r =
|
auto r =
|
||||||
|
|
@ -749,6 +766,18 @@ public:
|
||||||
return buffer->fill_rectangle(
|
return buffer->fill_rectangle(
|
||||||
x, y, width, height,
|
x, y, width, height,
|
||||||
Color::from_argb_uint8(alpha, red, green, blue));
|
Color::from_argb_uint8(alpha, red, green, blue));
|
||||||
|
},
|
||||||
|
.draw_texture =
|
||||||
|
[](void *self, int16_t x, int16_t y, int16_t width, int16_t handle,
|
||||||
|
const uint8_t *src, uint16_t src_stride, int16_t src_width,
|
||||||
|
int16_t src_height, uint8_t src_pixel_format, uint16_t src_dx,
|
||||||
|
uint16_t src_dy, uint16_t src_off_x, uint16_t src_off_y, uint32_t colorize,
|
||||||
|
uint8_t alpha, uint8_t rotation) {
|
||||||
|
auto *buffer = reinterpret_cast<TargetPixelBuffer<Rgb565Pixel> *>(self);
|
||||||
|
return buffer->draw_texture(x, y, width, handle, src, src_stride, src_width,
|
||||||
|
src_height, src_pixel_format, src_dx, src_dy,
|
||||||
|
src_off_x, src_off_y, colorize, alpha,
|
||||||
|
rotation);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
auto r = cbindgen_private::slint_software_renderer_render_accel_rgb565(inner,
|
auto r = cbindgen_private::slint_software_renderer_render_accel_rgb565(inner,
|
||||||
|
|
|
||||||
|
|
@ -384,6 +384,25 @@ mod software_renderer {
|
||||||
u8,
|
u8,
|
||||||
u8,
|
u8,
|
||||||
) -> bool,
|
) -> bool,
|
||||||
|
draw_texture: unsafe extern "C" fn(
|
||||||
|
CppTargetPixelBufferUserData,
|
||||||
|
i16,
|
||||||
|
i16,
|
||||||
|
i16,
|
||||||
|
i16,
|
||||||
|
*const u8,
|
||||||
|
u16,
|
||||||
|
i16,
|
||||||
|
i16,
|
||||||
|
u8,
|
||||||
|
u16,
|
||||||
|
u16,
|
||||||
|
u16,
|
||||||
|
u16,
|
||||||
|
u32,
|
||||||
|
u8,
|
||||||
|
u8,
|
||||||
|
) -> bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TargetPixelBuffer for CppRgb8TargetPixelBuffer {
|
impl TargetPixelBuffer for CppRgb8TargetPixelBuffer {
|
||||||
|
|
@ -424,6 +443,48 @@ mod software_renderer {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw_texture(
|
||||||
|
&mut self,
|
||||||
|
x: i16,
|
||||||
|
y: i16,
|
||||||
|
width: i16,
|
||||||
|
height: i16,
|
||||||
|
src: *const u8,
|
||||||
|
src_stride: u16,
|
||||||
|
src_width: i16,
|
||||||
|
src_height: i16,
|
||||||
|
src_pixel_format: u8,
|
||||||
|
dx: u16,
|
||||||
|
dy: u16,
|
||||||
|
off_x: u16,
|
||||||
|
off_y: u16,
|
||||||
|
colorize: u32,
|
||||||
|
alpha: u8,
|
||||||
|
rotation: u8,
|
||||||
|
) -> bool {
|
||||||
|
unsafe {
|
||||||
|
(self.draw_texture)(
|
||||||
|
self.user_data,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
src,
|
||||||
|
src_stride,
|
||||||
|
src_width,
|
||||||
|
src_height,
|
||||||
|
src_pixel_format,
|
||||||
|
dx,
|
||||||
|
dy,
|
||||||
|
off_x,
|
||||||
|
off_y,
|
||||||
|
colorize,
|
||||||
|
alpha,
|
||||||
|
rotation,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|
@ -447,6 +508,25 @@ mod software_renderer {
|
||||||
u8,
|
u8,
|
||||||
u8,
|
u8,
|
||||||
) -> bool,
|
) -> bool,
|
||||||
|
draw_texture: unsafe extern "C" fn(
|
||||||
|
CppTargetPixelBufferUserData,
|
||||||
|
i16,
|
||||||
|
i16,
|
||||||
|
i16,
|
||||||
|
i16,
|
||||||
|
*const u8,
|
||||||
|
u16,
|
||||||
|
i16,
|
||||||
|
i16,
|
||||||
|
u8,
|
||||||
|
u16,
|
||||||
|
u16,
|
||||||
|
u16,
|
||||||
|
u16,
|
||||||
|
u32,
|
||||||
|
u8,
|
||||||
|
u8,
|
||||||
|
) -> bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TargetPixelBuffer for CppRgb565TargetPixelBuffer {
|
impl TargetPixelBuffer for CppRgb565TargetPixelBuffer {
|
||||||
|
|
@ -487,6 +567,48 @@ mod software_renderer {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw_texture(
|
||||||
|
&mut self,
|
||||||
|
x: i16,
|
||||||
|
y: i16,
|
||||||
|
width: i16,
|
||||||
|
height: i16,
|
||||||
|
src: *const u8,
|
||||||
|
src_stride: u16,
|
||||||
|
src_width: i16,
|
||||||
|
src_height: i16,
|
||||||
|
src_pixel_format: u8,
|
||||||
|
dx: u16,
|
||||||
|
dy: u16,
|
||||||
|
off_x: u16,
|
||||||
|
off_y: u16,
|
||||||
|
colorize: u32,
|
||||||
|
alpha: u8,
|
||||||
|
rotation: u8,
|
||||||
|
) -> bool {
|
||||||
|
unsafe {
|
||||||
|
(self.draw_texture)(
|
||||||
|
self.user_data,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
src,
|
||||||
|
src_stride,
|
||||||
|
src_width,
|
||||||
|
src_height,
|
||||||
|
src_pixel_format,
|
||||||
|
dx,
|
||||||
|
dy,
|
||||||
|
off_x,
|
||||||
|
off_y,
|
||||||
|
colorize,
|
||||||
|
alpha,
|
||||||
|
rotation,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|
|
||||||
|
|
@ -394,6 +394,31 @@ mod private_api {
|
||||||
) -> bool {
|
) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Draw a texture into the buffer at the specified position with the given size and
|
||||||
|
/// colorized if needed. Returns true if the operation was successful; false if it could not be
|
||||||
|
/// implemented and instead the software renderer needs to draw the texture
|
||||||
|
fn draw_texture(
|
||||||
|
&mut self,
|
||||||
|
_x: i16,
|
||||||
|
_y: i16,
|
||||||
|
_width: i16,
|
||||||
|
_height: i16,
|
||||||
|
_src: *const u8,
|
||||||
|
_src_stride: u16,
|
||||||
|
_src_width: i16,
|
||||||
|
_src_height: i16,
|
||||||
|
_src_pixel_format: u8,
|
||||||
|
_src_dx: u16,
|
||||||
|
_src_dy: u16,
|
||||||
|
_src_off_x: u16,
|
||||||
|
_src_off_y: u16,
|
||||||
|
_colorize: u32,
|
||||||
|
_alpha: u8,
|
||||||
|
_rotation: u8,
|
||||||
|
) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -617,27 +642,14 @@ impl SoftwareRenderer {
|
||||||
};
|
};
|
||||||
drop(i);
|
drop(i);
|
||||||
|
|
||||||
let mut bg = TargetPixel::background();
|
let mut bg = PremultipliedRgbaColor::background();
|
||||||
// TODO: gradient background
|
// TODO: gradient background
|
||||||
// TODO: Use TargetPixelBuffer::fill_rectangle
|
PremultipliedRgbaColor::blend(&mut bg, background.color().into());
|
||||||
TargetPixel::blend(&mut bg, background.color().into());
|
|
||||||
let mut line = 0;
|
|
||||||
while let Some(next) = region_line_ranges(
|
|
||||||
&dirty_region,
|
|
||||||
line,
|
|
||||||
&mut renderer.actual_renderer.processor.dirty_range_cache,
|
|
||||||
) {
|
|
||||||
for l in line..next {
|
|
||||||
for r in &renderer.actual_renderer.processor.dirty_range_cache {
|
|
||||||
renderer.actual_renderer.processor.buffer.line_slice(l as usize)
|
|
||||||
[r.start as usize..r.end as usize]
|
|
||||||
.fill(bg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
line = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer.actual_renderer.processor.dirty_region = dirty_region.clone();
|
renderer.actual_renderer.processor.dirty_region = dirty_region.clone();
|
||||||
|
renderer.actual_renderer.processor.process_rectangle(
|
||||||
|
PhysicalRect::from_size(euclid::Size2D::new(size.width, size.height)),
|
||||||
|
bg,
|
||||||
|
);
|
||||||
|
|
||||||
for (component, origin) in components {
|
for (component, origin) in components {
|
||||||
crate::item_rendering::render_component_items(
|
crate::item_rendering::render_component_items(
|
||||||
|
|
@ -1241,15 +1253,38 @@ impl<T: TargetPixel, B: private_api::TargetPixelBuffer<Pixel = T>> RenderToBuffe
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_texture_impl(&mut self, geometry: PhysicalRect, texture: SceneTexture<'_>) {
|
fn process_texture_impl(&mut self, geometry: PhysicalRect, texture: SceneTexture<'_>) {
|
||||||
self.foreach_ranges(&geometry, |line, buffer, extra_left_clip, extra_right_clip| {
|
self.foreach_region(&geometry, |buffer, rect, extra_left_clip, extra_right_clip| {
|
||||||
draw_functions::draw_texture_line(
|
if !buffer.draw_texture(
|
||||||
&geometry,
|
rect.origin.x,
|
||||||
PhysicalLength::new(line),
|
rect.origin.y,
|
||||||
&texture,
|
rect.size.width,
|
||||||
buffer,
|
rect.size.height,
|
||||||
extra_left_clip,
|
texture.data.as_ptr(),
|
||||||
extra_right_clip,
|
texture.pixel_stride,
|
||||||
);
|
texture.source_size().width,
|
||||||
|
texture.source_size().height,
|
||||||
|
texture.format as u8,
|
||||||
|
texture.extra.dx.0,
|
||||||
|
texture.extra.dy.0,
|
||||||
|
texture.extra.off_x.0,
|
||||||
|
texture.extra.off_y.0,
|
||||||
|
texture.extra.colorize.as_argb_encoded(),
|
||||||
|
texture.extra.alpha,
|
||||||
|
texture.extra.rotation as u8,
|
||||||
|
) {
|
||||||
|
let begin = rect.min_x();
|
||||||
|
let end = rect.max_x();
|
||||||
|
for l in rect.min_y()..rect.max_y() {
|
||||||
|
draw_functions::draw_texture_line(
|
||||||
|
&geometry,
|
||||||
|
PhysicalLength::new(l),
|
||||||
|
&texture,
|
||||||
|
&mut buffer.line_slice(l as usize)[begin as usize..end as usize],
|
||||||
|
extra_left_clip,
|
||||||
|
extra_right_clip,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue