Use interior mutability for the cache

So we do not need a mutable reference to the Component
This commit is contained in:
Olivier Goffart 2020-06-04 14:03:30 +02:00
parent e4366efb67
commit 7b8df5ca9d
7 changed files with 33 additions and 30 deletions

View file

@ -116,14 +116,14 @@ fn to_eval_value<'a>(
fn show<'cx>(
cx: &mut CallContext<'cx, impl neon::object::This>,
mut component: ComponentBox,
component: ComponentBox,
presistent_context: persistent_context::PersistentContext<'cx>,
) -> JsResult<'cx, JsUndefined> {
cx.execute_scoped(|cx| {
let cx = RefCell::new(cx);
let cx_fn = move |callback: &GlobalContextCallback| { callback(&mut *cx.borrow_mut(), &presistent_context) };
GLOBAL_CONTEXT.set(&&cx_fn, || {
gl::sixtyfps_runtime_run_component_with_gl_renderer(component.borrow_mut());
gl::sixtyfps_runtime_run_component_with_gl_renderer(component.borrow());
})
});

View file

@ -288,10 +288,10 @@ pub fn sixtyfps(stream: TokenStream) -> TokenStream {
}
impl #component_id{
fn run(mut self) {
fn run(self) {
use sixtyfps::re_exports::*;
sixtyfps::re_exports::ComponentVTable_static!(static VT for #component_id);
sixtyfps_runtime_run_component_with_gl_renderer(VRefMut::new(&mut self));
sixtyfps_runtime_run_component_with_gl_renderer(VRef::new(&self));
}
}
);

View file

@ -1,4 +1,5 @@
use core::ptr::NonNull;
use std::cell::Cell;
use vtable::*;
pub type Rect = euclid::default::Rect<f32>;
@ -40,9 +41,9 @@ pub struct ComponentVTable {
#[repr(C)]
pub struct CachedRenderingData {
/// Used and modified by the backend, should be initialized to 0 by the user code
pub(crate) cache_index: usize,
pub(crate) cache_index: Cell<usize>,
/// Set to false initially and when changes happen that require updating the cache
pub(crate) cache_ok: bool,
pub(crate) cache_ok: Cell<bool>,
}
impl CachedRenderingData {
@ -53,10 +54,10 @@ impl CachedRenderingData {
&self,
cache: &'a crate::graphics::RenderingCache<GraphicsBackend>,
) -> Option<&'a GraphicsBackend::LowLevelRenderingPrimitive> {
if !self.cache_ok {
if !self.cache_ok.get() {
return None;
}
Some(cache.entry_at(self.cache_index))
Some(cache.entry_at(self.cache_index.get()))
}
}

View file

@ -1,4 +1,4 @@
use super::abi::datastructures::ItemRefMut;
use super::abi::datastructures::ItemRef;
use super::graphics::{
Frame, GraphicsBackend, HasRenderingPrimitive, RenderingCache, RenderingPrimitivesBuilder,
};
@ -7,13 +7,13 @@ use cgmath::{Matrix4, SquareMatrix, Vector3};
pub(crate) fn update_item_rendering_data<Backend: GraphicsBackend>(
context: &EvaluationContext,
mut item: ItemRefMut<'_>,
item: ItemRef<'_>,
rendering_cache: &mut RenderingCache<Backend>,
rendering_primitives_builder: &mut Backend::RenderingPrimitivesBuilder,
) {
let item_rendering_primitive = item.rendering_primitive(context);
let rendering_data = item.cached_rendering_data_offset_mut();
let rendering_data = item.cached_rendering_data_offset();
let last_rendering_primitive =
rendering_data.low_level_rendering_primitive(&rendering_cache).map(|ll| ll.primitive());
@ -30,9 +30,11 @@ pub(crate) fn update_item_rendering_data<Backend: GraphicsBackend>(
item_rendering_primitive, last_rendering_primitive
);
rendering_data.cache_index = rendering_cache
.allocate_entry(rendering_primitives_builder.create(item_rendering_primitive));
rendering_data.cache_ok = true;
rendering_data.cache_index.set(
rendering_cache
.allocate_entry(rendering_primitives_builder.create(item_rendering_primitive)),
);
rendering_data.cache_ok.set(true);
}
pub(crate) fn render_component_items<Backend: GraphicsBackend>(
@ -51,8 +53,8 @@ pub(crate) fn render_component_items<Backend: GraphicsBackend>(
transform * Matrix4::from_translation(Vector3::new(origin.x, origin.y, 0.));
let cached_rendering_data = item.cached_rendering_data_offset();
if cached_rendering_data.cache_ok {
let primitive = rendering_cache.entry_at(cached_rendering_data.cache_index);
if cached_rendering_data.cache_ok.get() {
let primitive = rendering_cache.entry_at(cached_rendering_data.cache_index.get());
frame.render_primitive(&primitive, &transform);
}

View file

@ -50,9 +50,9 @@ impl<GraphicsBackend: graphics::GraphicsBackend> MainWindow<GraphicsBackend> {
pub fn run_event_loop(
mut self,
mut component: vtable::VRefMut<crate::abi::datastructures::ComponentVTable>,
component: vtable::VRef<crate::abi::datastructures::ComponentVTable>,
mut prepare_rendering_function: impl FnMut(
vtable::VRefMut<'_, crate::abi::datastructures::ComponentVTable>,
vtable::VRef<'_, crate::abi::datastructures::ComponentVTable>,
&mut GraphicsBackend::RenderingPrimitivesBuilder,
&mut graphics::RenderingCache<GraphicsBackend>,
) + 'static,
@ -88,7 +88,7 @@ impl<GraphicsBackend: graphics::GraphicsBackend> MainWindow<GraphicsBackend> {
graphics_backend.new_rendering_primitives_builder();
prepare_rendering_function(
component.borrow_mut(),
component,
&mut rendering_primitives_builder,
&mut rendering_cache,
);
@ -99,10 +99,10 @@ impl<GraphicsBackend: graphics::GraphicsBackend> MainWindow<GraphicsBackend> {
let window = graphics_backend.window();
let size = window.inner_size();
let context = EvaluationContext { component: component.borrow() };
let context = EvaluationContext { component: component };
let mut frame =
graphics_backend.new_frame(size.width, size.height, &Color::WHITE);
render_function(component.borrow(), &context, &mut frame, &mut rendering_cache);
render_function(component, &context, &mut frame, &mut rendering_cache);
graphics_backend.present_frame(frame);
}
winit::event::Event::WindowEvent {
@ -117,8 +117,8 @@ impl<GraphicsBackend: graphics::GraphicsBackend> MainWindow<GraphicsBackend> {
event: winit::event::WindowEvent::MouseInput { state, .. },
..
} => {
let context = EvaluationContext { component: component.borrow() };
input_function(component.borrow(), &context, cursor_pos, state);
let context = EvaluationContext { component };
input_function(component, &context, cursor_pos, state);
let window = graphics_backend.window();
// FIXME: remove this, it should be based on actual changes rather than this
window.request_redraw();
@ -131,7 +131,7 @@ impl<GraphicsBackend: graphics::GraphicsBackend> MainWindow<GraphicsBackend> {
}
pub fn run_component<GraphicsBackend: graphics::GraphicsBackend + 'static>(
component: vtable::VRefMut<crate::abi::datastructures::ComponentVTable>,
component: vtable::VRef<crate::abi::datastructures::ComponentVTable>,
graphics_backend_factory: impl FnOnce(
&winit::event_loop::EventLoop<()>,
winit::window::WindowBuilder,
@ -143,10 +143,10 @@ pub fn run_component<GraphicsBackend: graphics::GraphicsBackend + 'static>(
component,
move |component, mut rendering_primitives_builder, rendering_cache| {
// Generate cached rendering data once
crate::abi::datastructures::visit_items_mut(
crate::abi::datastructures::visit_items(
component,
|component, item, _| {
let ctx = EvaluationContext { component: component.borrow() };
|item, _| {
let ctx = EvaluationContext { component };
item_rendering::update_item_rendering_data(
&ctx,
item,

View file

@ -501,7 +501,7 @@ impl Drop for GLRenderer {
/// vtable will is a *const, and inner like a *mut
#[no_mangle]
pub extern "C" fn sixtyfps_runtime_run_component_with_gl_renderer(
component: vtable::VRefMut<ComponentVTable>,
component: vtable::VRef<ComponentVTable>,
) {
sixtyfps_corelib::run_component(component, |event_loop, window_builder| {
GLRenderer::new(&event_loop, window_builder)

View file

@ -17,7 +17,7 @@ fn main() -> std::io::Result<()> {
}
};
let mut component = c.create();
gl::sixtyfps_runtime_run_component_with_gl_renderer(component.borrow_mut());
let component = c.create();
gl::sixtyfps_runtime_run_component_with_gl_renderer(component.borrow());
Ok(())
}