mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-30 23:27:22 +00:00
Improve performance of opacity rendering
Avoid an opacity layer also in the case where it is applied to an element with no children.
This commit is contained in:
parent
d6a569b8f8
commit
033cf3721e
3 changed files with 47 additions and 2 deletions
|
@ -690,9 +690,10 @@ impl ItemRenderer for GLItemRenderer {
|
|||
|
||||
fn visit_opacity(&mut self, opacity_item: Pin<&Opacity>, self_rc: &ItemRc) -> RenderingResult {
|
||||
let opacity = opacity_item.opacity();
|
||||
if opacity != 1.0 {
|
||||
if Opacity::need_layer(self_rc, opacity) {
|
||||
self.render_and_blend_layer(&opacity_item.cached_rendering_data, opacity, self_rc)
|
||||
} else {
|
||||
self.apply_opacity(opacity);
|
||||
opacity_item
|
||||
.cached_rendering_data
|
||||
.release(&mut self.graphics_window.graphics_cache.borrow_mut());
|
||||
|
|
|
@ -781,9 +781,10 @@ impl ItemRenderer for QtItemRenderer<'_> {
|
|||
|
||||
fn visit_opacity(&mut self, opacity_item: Pin<&Opacity>, self_rc: &ItemRc) -> RenderingResult {
|
||||
let opacity = opacity_item.opacity();
|
||||
if opacity != 1.0 {
|
||||
if Opacity::need_layer(self_rc, opacity) {
|
||||
self.render_and_blend_layer(&opacity_item.cached_rendering_data, opacity, self_rc)
|
||||
} else {
|
||||
self.apply_opacity(opacity);
|
||||
opacity_item.cached_rendering_data.release(&mut self.cache.borrow_mut());
|
||||
RenderingResult::ContinueRenderingChildren
|
||||
}
|
||||
|
|
|
@ -205,6 +205,18 @@ impl ItemRc {
|
|||
pub fn component(&self) -> vtable::VRc<ComponentVTable> {
|
||||
self.component.clone()
|
||||
}
|
||||
|
||||
/// Returns the number of child items for this item. Returns None if
|
||||
/// the number is dynamically determined.
|
||||
/// TODO: Remove the option when the Subtree trait exists and allows querying
|
||||
pub fn children_count(&self) -> Option<u32> {
|
||||
let comp_ref_pin = vtable::VRc::borrow_pin(&self.component);
|
||||
let item_tree = comp_ref_pin.as_ref().get_item_tree();
|
||||
match item_tree.as_slice()[self.index] {
|
||||
crate::item_tree::ItemTreeNode::Item { children_count, .. } => Some(children_count),
|
||||
crate::item_tree::ItemTreeNode::DynamicTree { .. } => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A Weak reference to an item that can be constructed from an ItemRc.
|
||||
|
@ -837,6 +849,37 @@ impl Item for Opacity {
|
|||
}
|
||||
}
|
||||
|
||||
impl Opacity {
|
||||
// This function determines the optimization opportunities for not having to render the
|
||||
// children of the Opacity element into a layer:
|
||||
// * The opacity item typically only one child (this is not guaranteed). If that item has
|
||||
// no children, then we can skip the layer and apply the opacity directly. This is not perfect though,
|
||||
// for example if the compiler inserts another synthetic element between the `Opacity` and the actual child,
|
||||
// then this check will apply a layer even though it might not actually be necessary.
|
||||
// * If the vale of the opacity is 1.0 then we don't need to do anything.
|
||||
pub fn need_layer(self_rc: &ItemRc, opacity: f32) -> bool {
|
||||
if opacity == 1.0 {
|
||||
return false;
|
||||
}
|
||||
let component_rc = self_rc.component();
|
||||
let component_ref = vtable::VRc::borrow_pin(&component_rc);
|
||||
let self_index = self_rc.index();
|
||||
// TODO: use first_child() once it exists
|
||||
let item_tree = component_ref.as_ref().get_item_tree();
|
||||
let target_item_index = match item_tree.as_slice()[self_index] {
|
||||
crate::item_tree::ItemTreeNode::Item { children_count, children_index, .. }
|
||||
if children_count == 1 =>
|
||||
{
|
||||
children_index as usize
|
||||
}
|
||||
_ => return true, // Dynamic tree or multiple children -> need layer
|
||||
};
|
||||
let target_item = ItemRc::new(component_rc.clone(), target_item_index);
|
||||
// any children? Then we need a layer
|
||||
target_item.children_count() != Some(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl ItemConsts for Opacity {
|
||||
const cached_rendering_data_offset: const_field_offset::FieldOffset<
|
||||
Opacity,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue