|
|
@ -207,6 +207,7 @@ impl ContextImpl { |
|
|
|
|
|
|
|
#[cfg(feature = "accesskit")] |
|
|
|
if self.is_accesskit_enabled { |
|
|
|
crate::profile_scope!("accesskit"); |
|
|
|
use crate::frame_state::AccessKitFrameState; |
|
|
|
let id = crate::accesskit_root_id(); |
|
|
|
let mut builder = accesskit::NodeBuilder::new(accesskit::Role::Window); |
|
|
@ -224,24 +225,32 @@ impl ContextImpl { |
|
|
|
|
|
|
|
/// Load fonts unless already loaded.
|
|
|
|
fn update_fonts_mut(&mut self) { |
|
|
|
crate::profile_function!(); |
|
|
|
|
|
|
|
let pixels_per_point = self.input.pixels_per_point(); |
|
|
|
let max_texture_side = self.input.max_texture_side; |
|
|
|
|
|
|
|
if let Some(font_definitions) = self.memory.new_font_definitions.take() { |
|
|
|
crate::profile_scope!("Fonts::new"); |
|
|
|
let fonts = Fonts::new(pixels_per_point, max_texture_side, font_definitions); |
|
|
|
self.fonts = Some(fonts); |
|
|
|
} |
|
|
|
|
|
|
|
let fonts = self.fonts.get_or_insert_with(|| { |
|
|
|
let font_definitions = FontDefinitions::default(); |
|
|
|
crate::profile_scope!("Fonts::new"); |
|
|
|
Fonts::new(pixels_per_point, max_texture_side, font_definitions) |
|
|
|
}); |
|
|
|
|
|
|
|
fonts.begin_frame(pixels_per_point, max_texture_side); |
|
|
|
{ |
|
|
|
crate::profile_scope!("Fonts::begin_frame"); |
|
|
|
fonts.begin_frame(pixels_per_point, max_texture_side); |
|
|
|
} |
|
|
|
|
|
|
|
if self.memory.options.preload_font_glyphs { |
|
|
|
crate::profile_scope!("preload_font_glyphs"); |
|
|
|
// Preload the most common characters for the most common fonts.
|
|
|
|
// This is not very important to do, but may a few GPU operations.
|
|
|
|
// This is not very important to do, but may save a few GPU operations.
|
|
|
|
for font_id in self.memory.options.style.text_styles.values() { |
|
|
|
fonts.lock().fonts.font(font_id).preload_common_characters(); |
|
|
|
} |
|
|
@ -370,6 +379,7 @@ impl Context { |
|
|
|
/// ```
|
|
|
|
#[must_use] |
|
|
|
pub fn run(&self, new_input: RawInput, run_ui: impl FnOnce(&Context)) -> FullOutput { |
|
|
|
crate::profile_function!(); |
|
|
|
self.begin_frame(new_input); |
|
|
|
run_ui(self); |
|
|
|
self.end_frame() |
|
|
@ -393,6 +403,7 @@ impl Context { |
|
|
|
/// // handle full_output
|
|
|
|
/// ```
|
|
|
|
pub fn begin_frame(&self, new_input: RawInput) { |
|
|
|
crate::profile_function!(); |
|
|
|
self.write(|ctx| ctx.begin_frame_mut(new_input)); |
|
|
|
} |
|
|
|
} |
|
|
@ -1207,6 +1218,7 @@ impl Context { |
|
|
|
/// Call at the end of each frame.
|
|
|
|
#[must_use] |
|
|
|
pub fn end_frame(&self) -> FullOutput { |
|
|
|
crate::profile_function!(); |
|
|
|
if self.input(|i| i.wants_repaint()) { |
|
|
|
self.request_repaint(); |
|
|
|
} |
|
|
@ -1230,6 +1242,7 @@ impl Context { |
|
|
|
|
|
|
|
#[cfg(feature = "accesskit")] |
|
|
|
{ |
|
|
|
crate::profile_scope!("accesskit"); |
|
|
|
let state = self.frame_state_mut(|fs| fs.accesskit_state.take()); |
|
|
|
if let Some(state) = state { |
|
|
|
let has_focus = self.input(|i| i.raw.focused); |
|
|
@ -1269,11 +1282,13 @@ impl Context { |
|
|
|
} |
|
|
|
|
|
|
|
fn drain_paint_lists(&self) -> Vec<ClippedShape> { |
|
|
|
crate::profile_function!(); |
|
|
|
self.write(|ctx| ctx.graphics.drain(ctx.memory.areas.order()).collect()) |
|
|
|
} |
|
|
|
|
|
|
|
/// Tessellate the given shapes into triangle meshes.
|
|
|
|
pub fn tessellate(&self, shapes: Vec<ClippedShape>) -> Vec<ClippedPrimitive> { |
|
|
|
crate::profile_function!(); |
|
|
|
// A tempting optimization is to reuse the tessellation from last frame if the
|
|
|
|
// shapes are the same, but just comparing the shapes takes about 50% of the time
|
|
|
|
// it takes to tessellate them, so it is not a worth optimization.
|
|
|
@ -1293,13 +1308,16 @@ impl Context { |
|
|
|
}; |
|
|
|
|
|
|
|
let paint_stats = PaintStats::from_shapes(&shapes); |
|
|
|
let clipped_primitives = tessellator::tessellate_shapes( |
|
|
|
pixels_per_point, |
|
|
|
tessellation_options, |
|
|
|
font_tex_size, |
|
|
|
prepared_discs, |
|
|
|
shapes, |
|
|
|
); |
|
|
|
let clipped_primitives = { |
|
|
|
crate::profile_scope!("tessellator::tessellate_shapes"); |
|
|
|
tessellator::tessellate_shapes( |
|
|
|
pixels_per_point, |
|
|
|
tessellation_options, |
|
|
|
font_tex_size, |
|
|
|
prepared_discs, |
|
|
|
shapes, |
|
|
|
) |
|
|
|
}; |
|
|
|
ctx.paint_stats = paint_stats.with_clipped_primitives(&clipped_primitives); |
|
|
|
clipped_primitives |
|
|
|
}) |
|
|
|