mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 06:11:16 +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()))
|
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
|
let image_id = canvas
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.create_image_empty(
|
.create_image_empty(
|
||||||
|
@ -149,7 +152,7 @@ impl CachedImage {
|
||||||
femtovg::ImageFlags::PREMULTIPLIED | femtovg::ImageFlags::FLIP_Y,
|
femtovg::ImageFlags::PREMULTIPLIED | femtovg::ImageFlags::FLIP_Y,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Self::new_on_gpu(canvas, image_id)
|
Self::new_on_gpu(canvas, image_id).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "svg")]
|
#[cfg(feature = "svg")]
|
||||||
|
@ -352,6 +355,9 @@ impl CachedImage {
|
||||||
&canvas,
|
&canvas,
|
||||||
size.width.ceil() as usize,
|
size.width.ceil() as usize,
|
||||||
size.height.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() {
|
let filtered_image_id = match &*filtered_image.0.borrow() {
|
||||||
|
|
|
@ -934,7 +934,7 @@ impl ItemRenderer for GLItemRenderer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cache_entry = self
|
let cache_entry = match self
|
||||||
.graphics_window
|
.graphics_window
|
||||||
.graphics_cache
|
.graphics_cache
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
@ -961,7 +961,7 @@ impl ItemRenderer for GLItemRenderer {
|
||||||
&self.shared_data.canvas,
|
&self.shared_data.canvas,
|
||||||
shadow_image_width,
|
shadow_image_width,
|
||||||
shadow_image_height,
|
shadow_image_height,
|
||||||
);
|
)?;
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut canvas = self.shared_data.canvas.borrow_mut();
|
let mut canvas = self.shared_data.canvas.borrow_mut();
|
||||||
|
@ -1033,8 +1033,10 @@ impl ItemRenderer for GLItemRenderer {
|
||||||
Rc::new(shadow_image)
|
Rc::new(shadow_image)
|
||||||
})
|
})
|
||||||
.into()
|
.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();
|
let shadow_image = cache_entry.as_image();
|
||||||
|
|
||||||
|
@ -1514,11 +1516,15 @@ impl GLItemRenderer {
|
||||||
let layer_width = path_bounds.maxx - path_bounds.minx;
|
let layer_width = path_bounds.maxx - path_bounds.minx;
|
||||||
let layer_height = path_bounds.maxy - path_bounds.miny;
|
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,
|
&self.shared_data.canvas,
|
||||||
layer_width as _,
|
layer_width as _,
|
||||||
layer_height 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();
|
let mut canvas = self.shared_data.canvas.borrow_mut();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue