mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 06:11:16 +00:00
Free graphics resources without item tree traversal
This commit is contained in:
parent
ba0ec058ab
commit
7a5113ece1
7 changed files with 54 additions and 40 deletions
|
@ -96,11 +96,9 @@ public:
|
|||
sixtyfps_component_window_set_scale_factor(&inner, value);
|
||||
}
|
||||
|
||||
template<typename Component>
|
||||
void free_graphics_resources(Component *c) const
|
||||
void free_graphics_resources(const sixtyfps::Slice<ItemRef> &items) const
|
||||
{
|
||||
cbindgen_private::sixtyfps_component_window_free_graphics_resources(
|
||||
&inner, vtable::VRef<ComponentVTable> { &Component::component_type, c });
|
||||
cbindgen_private::sixtyfps_component_window_free_graphics_resources(&inner, &items);
|
||||
}
|
||||
|
||||
void set_focus_item(vtable::VRef<ComponentVTable> c, vtable::VRef<ItemVTable> item)
|
||||
|
|
|
@ -894,6 +894,7 @@ fn generate_component(
|
|||
let mut repeated_input_branch = vec![];
|
||||
let mut repeater_layout_code = vec![];
|
||||
let mut tree_array = vec![];
|
||||
let mut item_names_and_vt_symbols = vec![];
|
||||
let mut repeater_count = 0;
|
||||
super::build_array_helper(component, |item_rc, children_offset, is_flickable_rect| {
|
||||
let item = item_rc.borrow();
|
||||
|
@ -944,6 +945,8 @@ fn generate_component(
|
|||
children_offset,
|
||||
));
|
||||
handle_item(item_rc, &mut component_struct, &mut init);
|
||||
item_names_and_vt_symbols
|
||||
.push((item.id.clone(), item.base_type.as_native().vtable_symbol.clone()));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -979,7 +982,15 @@ fn generate_component(
|
|||
if component.parent_element.upgrade().is_some() {
|
||||
destructor.push("if (!parent) return;".to_owned())
|
||||
}
|
||||
destructor.push("self->window.free_graphics_resources(this);".into());
|
||||
if !item_names_and_vt_symbols.is_empty() {
|
||||
destructor.push("sixtyfps::private_api::ItemRef items[] = {".into());
|
||||
destructor.push(item_names_and_vt_symbols.iter()
|
||||
.map(|(item_name, vt_symbol)|
|
||||
format!("{{ &sixtyfps::private_api::{vt}, const_cast<decltype(this->{id})*>(&this->{id}) }}", id = item_name, vt = vt_symbol)
|
||||
).join(","));
|
||||
destructor.push("};".into());
|
||||
destructor.push("window.free_graphics_resources(sixtyfps::Slice<sixtyfps::private_api::ItemRef>{items, std::size(items)});".into());
|
||||
}
|
||||
|
||||
component_struct.members.push((
|
||||
Access::Public,
|
||||
|
|
|
@ -611,7 +611,10 @@ fn generate_component(
|
|||
Some(quote!(impl sixtyfps::re_exports::PinnedDrop for #component_id {
|
||||
fn drop(self: core::pin::Pin<&mut #component_id>) {
|
||||
use sixtyfps::re_exports::*;
|
||||
self.window.free_graphics_resources(VRef::new_pin(self.as_ref()));
|
||||
let items = [
|
||||
#(VRef::new_pin(Self::FIELD_OFFSETS.#item_names.apply_pin(self.as_ref())),)*
|
||||
];
|
||||
self.window.free_graphics_resources(&Slice::from_slice(&items));
|
||||
}
|
||||
})),
|
||||
quote!(#[pin_drop]),
|
||||
|
|
|
@ -13,7 +13,11 @@ LICENSE END */
|
|||
[GenericWindow] trait used by the generated code and the run-time to change
|
||||
aspects of windows on the screen.
|
||||
*/
|
||||
use crate::component::{ComponentRc, ComponentVTable};
|
||||
use crate::{
|
||||
component::{ComponentRc, ComponentVTable},
|
||||
items::ItemRef,
|
||||
slice::Slice,
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
use std::{
|
||||
convert::TryInto,
|
||||
|
@ -91,10 +95,7 @@ pub trait GenericWindow {
|
|||
|
||||
/// This function is called by the generated code when a component and therefore its tree of items are destroyed. The
|
||||
/// implementation typically uses this to free the underlying graphics resources cached via [`crate::graphics::RenderingCache`].
|
||||
fn free_graphics_resources(
|
||||
self: Rc<Self>,
|
||||
component: core::pin::Pin<crate::component::ComponentRef>,
|
||||
);
|
||||
fn free_graphics_resources<'a>(self: Rc<Self>, items: &Slice<'a, Pin<ItemRef<'a>>>);
|
||||
/// Installs a binding on the specified property that's toggled whenever the text cursor is supposed to be visible or not.
|
||||
fn set_cursor_blink_binding(&self, prop: &crate::properties::Property<bool>);
|
||||
|
||||
|
@ -151,11 +152,8 @@ impl ComponentWindow {
|
|||
|
||||
/// This function is called by the generated code when a component and therefore its tree of items are destroyed. The
|
||||
/// implementation typically uses this to free the underlying graphics resources cached via [RenderingCache][`crate::graphics::RenderingCache`].
|
||||
pub fn free_graphics_resources(
|
||||
&self,
|
||||
component: core::pin::Pin<crate::component::ComponentRef>,
|
||||
) {
|
||||
self.0.clone().free_graphics_resources(component);
|
||||
pub fn free_graphics_resources<'a>(&self, items: &Slice<'a, Pin<ItemRef<'a>>>) {
|
||||
self.0.clone().free_graphics_resources(items);
|
||||
}
|
||||
|
||||
/// Installs a binding on the specified property that's toggled whenever the text cursor is supposed to be visible or not.
|
||||
|
@ -599,12 +597,12 @@ pub mod ffi {
|
|||
|
||||
/// Sets the window scale factor, merely for testing purposes.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sixtyfps_component_window_free_graphics_resources(
|
||||
pub unsafe extern "C" fn sixtyfps_component_window_free_graphics_resources<'a>(
|
||||
handle: *const ComponentWindowOpaque,
|
||||
component: Pin<VRef<ComponentVTable>>,
|
||||
items: &Slice<'a, Pin<ItemRef<'a>>>,
|
||||
) {
|
||||
let window = &*(handle as *const ComponentWindow);
|
||||
window.free_graphics_resources(component)
|
||||
window.free_graphics_resources(items)
|
||||
}
|
||||
|
||||
/// Sets the focus item.
|
||||
|
|
|
@ -20,7 +20,6 @@ LICENSE END */
|
|||
created by the backend in a type-erased manner.
|
||||
*/
|
||||
extern crate alloc;
|
||||
use crate::component::{ComponentRc, ComponentWeak};
|
||||
use crate::input::{KeyEvent, KeyboardModifiers, MouseEvent, MouseEventType};
|
||||
use crate::items::ItemRef;
|
||||
use crate::properties::{InterpolatedPropertyValue, Property, PropertyTracker};
|
||||
|
@ -29,6 +28,10 @@ use crate::rtti::{BuiltinItem, FieldInfo, PropertyInfo, ValueType};
|
|||
use crate::SharedArray;
|
||||
#[cfg(feature = "rtti")]
|
||||
use crate::Signal;
|
||||
use crate::{
|
||||
component::{ComponentRc, ComponentWeak},
|
||||
slice::Slice,
|
||||
};
|
||||
|
||||
use auto_enums::auto_enum;
|
||||
use cgmath::Matrix4;
|
||||
|
@ -820,14 +823,11 @@ impl<Backend: GraphicsBackend> crate::eventloop::GenericWindow for GraphicsWindo
|
|||
)
|
||||
}
|
||||
|
||||
fn free_graphics_resources(
|
||||
self: Rc<Self>,
|
||||
component: core::pin::Pin<crate::component::ComponentRef>,
|
||||
) {
|
||||
fn free_graphics_resources<'a>(self: Rc<Self>, items: &Slice<'a, Pin<ItemRef<'a>>>) {
|
||||
match &*self.map_state.borrow() {
|
||||
GraphicsWindowBackendState::Unmapped => {}
|
||||
GraphicsWindowBackendState::Mapped(window) => {
|
||||
crate::item_rendering::free_item_rendering_data(component, &window.rendering_cache)
|
||||
crate::item_rendering::free_item_rendering_data(items, &window.rendering_cache)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@ use super::graphics::{
|
|||
Frame, GraphicsBackend, GraphicsWindow, RenderingCache, RenderingPrimitivesBuilder,
|
||||
};
|
||||
use super::items::ItemRef;
|
||||
use crate::eventloop::ComponentWindow;
|
||||
use crate::item_tree::ItemVisitorResult;
|
||||
use crate::{eventloop::ComponentWindow, slice::Slice};
|
||||
use cgmath::{Matrix4, SquareMatrix, Vector3};
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
||||
|
@ -123,18 +123,12 @@ pub(crate) fn render_component_items<Backend: GraphicsBackend>(
|
|||
);
|
||||
}
|
||||
|
||||
pub(crate) fn free_item_rendering_data<Backend: GraphicsBackend>(
|
||||
component: crate::component::ComponentRefPin,
|
||||
pub(crate) fn free_item_rendering_data<'a, Backend: GraphicsBackend>(
|
||||
items: &Slice<'a, core::pin::Pin<ItemRef<'a>>>,
|
||||
rendering_cache: &RefCell<RenderingCache<Backend>>,
|
||||
) {
|
||||
crate::item_tree::visit_items(
|
||||
component,
|
||||
crate::item_tree::TraversalOrder::FrontToBack,
|
||||
|_, item, _| {
|
||||
for item in items.iter() {
|
||||
let cached_rendering_data = item.cached_rendering_data_offset();
|
||||
cached_rendering_data.release(rendering_cache);
|
||||
ItemVisitorResult::Continue(())
|
||||
},
|
||||
(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,9 +77,19 @@ impl<'id> ComponentBox<'id> {
|
|||
|
||||
impl<'id> Drop for ComponentBox<'id> {
|
||||
fn drop(&mut self) {
|
||||
match eval::window_ref(self.borrow_instance()) {
|
||||
let instance_ref = self.borrow_instance();
|
||||
match eval::window_ref(instance_ref) {
|
||||
Some(window) => {
|
||||
window.free_graphics_resources(self.borrow());
|
||||
let items = self
|
||||
.component_type
|
||||
.items
|
||||
.values()
|
||||
.map(|item_within_component| unsafe {
|
||||
item_within_component.item_from_component(instance_ref.as_ptr())
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
window.free_graphics_resources(&Slice::from_slice(items.as_slice()));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue