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>( fn show<'cx>(
cx: &mut CallContext<'cx, impl neon::object::This>, cx: &mut CallContext<'cx, impl neon::object::This>,
mut component: ComponentBox, component: ComponentBox,
presistent_context: persistent_context::PersistentContext<'cx>, presistent_context: persistent_context::PersistentContext<'cx>,
) -> JsResult<'cx, JsUndefined> { ) -> JsResult<'cx, JsUndefined> {
cx.execute_scoped(|cx| { cx.execute_scoped(|cx| {
let cx = RefCell::new(cx); let cx = RefCell::new(cx);
let cx_fn = move |callback: &GlobalContextCallback| { callback(&mut *cx.borrow_mut(), &presistent_context) }; let cx_fn = move |callback: &GlobalContextCallback| { callback(&mut *cx.borrow_mut(), &presistent_context) };
GLOBAL_CONTEXT.set(&&cx_fn, || { 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{ impl #component_id{
fn run(mut self) { fn run(self) {
use sixtyfps::re_exports::*; use sixtyfps::re_exports::*;
sixtyfps::re_exports::ComponentVTable_static!(static VT for #component_id); 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 core::ptr::NonNull;
use std::cell::Cell;
use vtable::*; use vtable::*;
pub type Rect = euclid::default::Rect<f32>; pub type Rect = euclid::default::Rect<f32>;
@ -40,9 +41,9 @@ pub struct ComponentVTable {
#[repr(C)] #[repr(C)]
pub struct CachedRenderingData { pub struct CachedRenderingData {
/// Used and modified by the backend, should be initialized to 0 by the user code /// 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 /// 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 { impl CachedRenderingData {
@ -53,10 +54,10 @@ impl CachedRenderingData {
&self, &self,
cache: &'a crate::graphics::RenderingCache<GraphicsBackend>, cache: &'a crate::graphics::RenderingCache<GraphicsBackend>,
) -> Option<&'a GraphicsBackend::LowLevelRenderingPrimitive> { ) -> Option<&'a GraphicsBackend::LowLevelRenderingPrimitive> {
if !self.cache_ok { if !self.cache_ok.get() {
return None; 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::{ use super::graphics::{
Frame, GraphicsBackend, HasRenderingPrimitive, RenderingCache, RenderingPrimitivesBuilder, Frame, GraphicsBackend, HasRenderingPrimitive, RenderingCache, RenderingPrimitivesBuilder,
}; };
@ -7,13 +7,13 @@ use cgmath::{Matrix4, SquareMatrix, Vector3};
pub(crate) fn update_item_rendering_data<Backend: GraphicsBackend>( pub(crate) fn update_item_rendering_data<Backend: GraphicsBackend>(
context: &EvaluationContext, context: &EvaluationContext,
mut item: ItemRefMut<'_>, item: ItemRef<'_>,
rendering_cache: &mut RenderingCache<Backend>, rendering_cache: &mut RenderingCache<Backend>,
rendering_primitives_builder: &mut Backend::RenderingPrimitivesBuilder, rendering_primitives_builder: &mut Backend::RenderingPrimitivesBuilder,
) { ) {
let item_rendering_primitive = item.rendering_primitive(context); 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 = let last_rendering_primitive =
rendering_data.low_level_rendering_primitive(&rendering_cache).map(|ll| ll.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 item_rendering_primitive, last_rendering_primitive
); );
rendering_data.cache_index = rendering_cache rendering_data.cache_index.set(
.allocate_entry(rendering_primitives_builder.create(item_rendering_primitive)); rendering_cache
rendering_data.cache_ok = true; .allocate_entry(rendering_primitives_builder.create(item_rendering_primitive)),
);
rendering_data.cache_ok.set(true);
} }
pub(crate) fn render_component_items<Backend: GraphicsBackend>( 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.)); transform * Matrix4::from_translation(Vector3::new(origin.x, origin.y, 0.));
let cached_rendering_data = item.cached_rendering_data_offset(); let cached_rendering_data = item.cached_rendering_data_offset();
if cached_rendering_data.cache_ok { if cached_rendering_data.cache_ok.get() {
let primitive = rendering_cache.entry_at(cached_rendering_data.cache_index); let primitive = rendering_cache.entry_at(cached_rendering_data.cache_index.get());
frame.render_primitive(&primitive, &transform); frame.render_primitive(&primitive, &transform);
} }

View file

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

View file

@ -501,7 +501,7 @@ impl Drop for GLRenderer {
/// vtable will is a *const, and inner like a *mut /// vtable will is a *const, and inner like a *mut
#[no_mangle] #[no_mangle]
pub extern "C" fn sixtyfps_runtime_run_component_with_gl_renderer( 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| { sixtyfps_corelib::run_component(component, |event_loop, window_builder| {
GLRenderer::new(&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(); let component = c.create();
gl::sixtyfps_runtime_run_component_with_gl_renderer(component.borrow_mut()); gl::sixtyfps_runtime_run_component_with_gl_renderer(component.borrow());
Ok(()) Ok(())
} }