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