mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-30 22:01:13 +00:00
GL backend: Avoid run-time opengl errors with clipped zero width or height rectangles
If a Rectangle has a border-radius and clipping, we use an FBO to render the children and then use femtovg's stencil clipping. If the Rectangle has a zero width or height, we would end up trying to create a texture with such dimensions, which produces run-time opengl errors. We can detect this situation and avoid it early on. The same might happen for shadows. Fixes #377
This commit is contained in:
parent
603c5df47a
commit
25fac2bcd5
2 changed files with 20 additions and 8 deletions
|
@ -139,7 +139,10 @@ impl CachedImage {
|
|||
Self(RefCell::new(Texture { id: image_id, canvas: canvas.clone() }.into()))
|
||||
}
|
||||
|
||||
pub fn new_empty_on_gpu(canvas: &CanvasRc, width: usize, height: usize) -> Self {
|
||||
pub fn new_empty_on_gpu(canvas: &CanvasRc, width: usize, height: usize) -> Option<Self> {
|
||||
if width == 0 || height == 0 {
|
||||
return None;
|
||||
}
|
||||
let image_id = canvas
|
||||
.borrow_mut()
|
||||
.create_image_empty(
|
||||
|
@ -149,7 +152,7 @@ impl CachedImage {
|
|||
femtovg::ImageFlags::PREMULTIPLIED | femtovg::ImageFlags::FLIP_Y,
|
||||
)
|
||||
.unwrap();
|
||||
Self::new_on_gpu(canvas, image_id)
|
||||
Self::new_on_gpu(canvas, image_id).into()
|
||||
}
|
||||
|
||||
#[cfg(feature = "svg")]
|
||||
|
@ -352,6 +355,9 @@ impl CachedImage {
|
|||
&canvas,
|
||||
size.width.ceil() as usize,
|
||||
size.height.ceil() as usize,
|
||||
)
|
||||
.expect(
|
||||
"internal error: this can only fail if the filtered image was zero width or height",
|
||||
);
|
||||
|
||||
let filtered_image_id = match &*filtered_image.0.borrow() {
|
||||
|
|
|
@ -934,7 +934,7 @@ impl ItemRenderer for GLItemRenderer {
|
|||
return;
|
||||
}
|
||||
|
||||
let cache_entry = self
|
||||
let cache_entry = match self
|
||||
.graphics_window
|
||||
.graphics_cache
|
||||
.borrow_mut()
|
||||
|
@ -961,7 +961,7 @@ impl ItemRenderer for GLItemRenderer {
|
|||
&self.shared_data.canvas,
|
||||
shadow_image_width,
|
||||
shadow_image_height,
|
||||
);
|
||||
)?;
|
||||
|
||||
{
|
||||
let mut canvas = self.shared_data.canvas.borrow_mut();
|
||||
|
@ -1033,8 +1033,10 @@ impl ItemRenderer for GLItemRenderer {
|
|||
Rc::new(shadow_image)
|
||||
})
|
||||
.into()
|
||||
})
|
||||
.expect("internal error: creation of the cached shadow image must always succeed");
|
||||
}) {
|
||||
Some(cached_shadow_image) => cached_shadow_image,
|
||||
None => return, // Zero width or height shadow
|
||||
};
|
||||
|
||||
let shadow_image = cache_entry.as_image();
|
||||
|
||||
|
@ -1514,11 +1516,15 @@ impl GLItemRenderer {
|
|||
let layer_width = path_bounds.maxx - path_bounds.minx;
|
||||
let layer_height = path_bounds.maxy - path_bounds.miny;
|
||||
|
||||
let clip_buffer_img = CachedImage::new_empty_on_gpu(
|
||||
let clip_buffer_img = match CachedImage::new_empty_on_gpu(
|
||||
&self.shared_data.canvas,
|
||||
layer_width as _,
|
||||
layer_height as _,
|
||||
);
|
||||
) {
|
||||
Some(clip_buffer) => clip_buffer,
|
||||
None => return, // Zero width or height clip path
|
||||
};
|
||||
|
||||
{
|
||||
let mut canvas = self.shared_data.canvas.borrow_mut();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue