Optimize: store a reference to the target PaintList in Painter
Saves us a hash lookup for each paint call, giving us 5% perf gain
This commit is contained in:
parent
17983e1bbc
commit
4984d51f99
3 changed files with 24 additions and 20 deletions
|
@ -685,7 +685,9 @@ impl Context {
|
|||
/// Move all the graphics at the given layer.
|
||||
/// Can be used to implement drag-and-drop (see relevant demo).
|
||||
pub fn translate_layer(&self, layer_id: LayerId, delta: Vec2) {
|
||||
self.graphics().list(layer_id).translate(delta);
|
||||
if delta != Vec2::ZERO {
|
||||
self.graphics().list(layer_id).lock().translate(delta);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn layer_id_at(&self, pos: Pos2) -> Option<LayerId> {
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
use crate::{Id, *};
|
||||
use epaint::ahash::AHashMap;
|
||||
use epaint::mutex::Mutex;
|
||||
use epaint::{ClippedShape, Shape};
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Different layer categories
|
||||
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
|
||||
|
@ -120,10 +122,10 @@ impl PaintList {
|
|||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub(crate) struct GraphicLayers([AHashMap<Id, PaintList>; Order::COUNT]);
|
||||
pub(crate) struct GraphicLayers([AHashMap<Id, Arc<Mutex<PaintList>>>; Order::COUNT]);
|
||||
|
||||
impl GraphicLayers {
|
||||
pub fn list(&mut self, layer_id: LayerId) -> &mut PaintList {
|
||||
pub fn list(&mut self, layer_id: LayerId) -> &Arc<Mutex<PaintList>> {
|
||||
self.0[layer_id.order as usize]
|
||||
.entry(layer_id.id)
|
||||
.or_default()
|
||||
|
@ -138,20 +140,20 @@ impl GraphicLayers {
|
|||
// If a layer is empty at the start of the frame
|
||||
// the nobody has added to it, and it is old and defunct.
|
||||
// Free it to save memory:
|
||||
order_map.retain(|_, list| !list.is_empty());
|
||||
order_map.retain(|_, list| !list.lock().is_empty());
|
||||
|
||||
// First do the layers part of area_order:
|
||||
for layer_id in area_order {
|
||||
if layer_id.order == order {
|
||||
if let Some(shapes) = order_map.get_mut(&layer_id.id) {
|
||||
all_shapes.extend(shapes.0.drain(..));
|
||||
if let Some(list) = order_map.get_mut(&layer_id.id) {
|
||||
all_shapes.extend(list.lock().0.drain(..));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also draw areas that are missing in `area_order`:
|
||||
for shapes in order_map.values_mut() {
|
||||
all_shapes.extend(shapes.0.drain(..));
|
||||
all_shapes.extend(shapes.lock().0.drain(..));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use crate::{
|
||||
emath::{Align2, Pos2, Rect, Vec2},
|
||||
layers::{LayerId, ShapeIdx},
|
||||
layers::{LayerId, PaintList, ShapeIdx},
|
||||
Color32, CtxRef,
|
||||
};
|
||||
use epaint::{
|
||||
mutex::Mutex,
|
||||
text::{Fonts, Galley, TextStyle},
|
||||
Shape, Stroke,
|
||||
};
|
||||
|
@ -19,6 +20,8 @@ pub struct Painter {
|
|||
/// Where we paint
|
||||
layer_id: LayerId,
|
||||
|
||||
paint_list: std::sync::Arc<Mutex<PaintList>>,
|
||||
|
||||
/// Everything painted in this `Painter` will be clipped against this.
|
||||
/// This means nothing outside of this rectangle will be visible on screen.
|
||||
clip_rect: Rect,
|
||||
|
@ -30,9 +33,11 @@ pub struct Painter {
|
|||
|
||||
impl Painter {
|
||||
pub fn new(ctx: CtxRef, layer_id: LayerId, clip_rect: Rect) -> Self {
|
||||
let paint_list = ctx.graphics().list(layer_id).clone();
|
||||
Self {
|
||||
ctx,
|
||||
layer_id,
|
||||
paint_list,
|
||||
clip_rect,
|
||||
fade_to_color: None,
|
||||
}
|
||||
|
@ -40,8 +45,10 @@ impl Painter {
|
|||
|
||||
#[must_use]
|
||||
pub fn with_layer_id(self, layer_id: LayerId) -> Self {
|
||||
let paint_list = self.ctx.graphics().list(layer_id).clone();
|
||||
Self {
|
||||
ctx: self.ctx,
|
||||
paint_list,
|
||||
layer_id,
|
||||
clip_rect: self.clip_rect,
|
||||
fade_to_color: None,
|
||||
|
@ -51,6 +58,7 @@ impl Painter {
|
|||
/// redirect
|
||||
pub fn set_layer_id(&mut self, layer_id: LayerId) {
|
||||
self.layer_id = layer_id;
|
||||
self.paint_list = self.ctx.graphics().list(self.layer_id).clone();
|
||||
}
|
||||
|
||||
/// If set, colors will be modified to look like this
|
||||
|
@ -66,6 +74,7 @@ impl Painter {
|
|||
Self {
|
||||
ctx: self.ctx.clone(),
|
||||
layer_id: self.layer_id,
|
||||
paint_list: self.paint_list.clone(),
|
||||
clip_rect: rect.intersect(self.clip_rect),
|
||||
fade_to_color: self.fade_to_color,
|
||||
}
|
||||
|
@ -129,10 +138,7 @@ impl Painter {
|
|||
/// NOTE: all coordinates are screen coordinates!
|
||||
pub fn add(&self, mut shape: Shape) -> ShapeIdx {
|
||||
self.transform_shape(&mut shape);
|
||||
self.ctx
|
||||
.graphics()
|
||||
.list(self.layer_id)
|
||||
.add(self.clip_rect, shape)
|
||||
self.paint_list.lock().add(self.clip_rect, shape)
|
||||
}
|
||||
|
||||
/// Add many shapes at once.
|
||||
|
@ -146,20 +152,14 @@ impl Painter {
|
|||
}
|
||||
}
|
||||
|
||||
self.ctx
|
||||
.graphics()
|
||||
.list(self.layer_id)
|
||||
.extend(self.clip_rect, shapes);
|
||||
self.paint_list.lock().extend(self.clip_rect, shapes);
|
||||
}
|
||||
}
|
||||
|
||||
/// Modify an existing [`Shape`].
|
||||
pub fn set(&self, idx: ShapeIdx, mut shape: Shape) {
|
||||
self.transform_shape(&mut shape);
|
||||
self.ctx
|
||||
.graphics()
|
||||
.list(self.layer_id)
|
||||
.set(idx, self.clip_rect, shape)
|
||||
self.paint_list.lock().set(idx, self.clip_rect, shape)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue