Refactor TextLayout to use Rc<RefCell> instead of Arc<Mutex> for improved performance (#27177)
Since `TextLayout` is not shared by multiple threads, changing it to
`Rc<RefCell<T>>` should improve performance.
I also found several codes with the same problem. If you think this
change is beneficial, I will continue to improve it in the subsequent
PR. 🙂
Release Notes:
- N/A
This commit is contained in:
parent
6143da95fc
commit
1db621dc50
1 changed files with 12 additions and 17 deletions
|
@ -6,7 +6,6 @@ use crate::{
|
|||
WrappedLineLayout,
|
||||
};
|
||||
use anyhow::anyhow;
|
||||
use parking_lot::{Mutex, MutexGuard};
|
||||
use smallvec::SmallVec;
|
||||
use std::{
|
||||
cell::{Cell, RefCell},
|
||||
|
@ -277,7 +276,7 @@ impl IntoElement for StyledText {
|
|||
|
||||
/// The Layout for TextElement. This can be used to map indices to pixels and vice versa.
|
||||
#[derive(Default, Clone)]
|
||||
pub struct TextLayout(Arc<Mutex<Option<TextLayoutInner>>>);
|
||||
pub struct TextLayout(Rc<RefCell<Option<TextLayoutInner>>>);
|
||||
|
||||
struct TextLayoutInner {
|
||||
lines: SmallVec<[WrappedLine; 1]>,
|
||||
|
@ -288,10 +287,6 @@ struct TextLayoutInner {
|
|||
}
|
||||
|
||||
impl TextLayout {
|
||||
fn lock(&self) -> MutexGuard<Option<TextLayoutInner>> {
|
||||
self.0.lock()
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&self,
|
||||
text: SharedString,
|
||||
|
@ -341,7 +336,7 @@ impl TextLayout {
|
|||
(None, None)
|
||||
};
|
||||
|
||||
if let Some(text_layout) = element_state.0.lock().as_ref() {
|
||||
if let Some(text_layout) = element_state.0.borrow().as_ref() {
|
||||
if text_layout.size.is_some()
|
||||
&& (wrap_width.is_none() || wrap_width == text_layout.wrap_width)
|
||||
{
|
||||
|
@ -367,7 +362,7 @@ impl TextLayout {
|
|||
)
|
||||
.log_err()
|
||||
else {
|
||||
element_state.lock().replace(TextLayoutInner {
|
||||
element_state.0.borrow_mut().replace(TextLayoutInner {
|
||||
lines: Default::default(),
|
||||
line_height,
|
||||
wrap_width,
|
||||
|
@ -384,7 +379,7 @@ impl TextLayout {
|
|||
size.width = size.width.max(line_size.width).ceil();
|
||||
}
|
||||
|
||||
element_state.lock().replace(TextLayoutInner {
|
||||
element_state.0.borrow_mut().replace(TextLayoutInner {
|
||||
lines,
|
||||
line_height,
|
||||
wrap_width,
|
||||
|
@ -400,7 +395,7 @@ impl TextLayout {
|
|||
}
|
||||
|
||||
fn prepaint(&self, bounds: Bounds<Pixels>, text: &str) {
|
||||
let mut element_state = self.lock();
|
||||
let mut element_state = self.0.borrow_mut();
|
||||
let element_state = element_state
|
||||
.as_mut()
|
||||
.ok_or_else(|| anyhow!("measurement has not been performed on {}", text))
|
||||
|
@ -409,7 +404,7 @@ impl TextLayout {
|
|||
}
|
||||
|
||||
fn paint(&self, text: &str, window: &mut Window, cx: &mut App) {
|
||||
let element_state = self.lock();
|
||||
let element_state = self.0.borrow();
|
||||
let element_state = element_state
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("measurement has not been performed on {}", text))
|
||||
|
@ -438,7 +433,7 @@ impl TextLayout {
|
|||
|
||||
/// Get the byte index into the input of the pixel position.
|
||||
pub fn index_for_position(&self, mut position: Point<Pixels>) -> Result<usize, usize> {
|
||||
let element_state = self.lock();
|
||||
let element_state = self.0.borrow();
|
||||
let element_state = element_state
|
||||
.as_ref()
|
||||
.expect("measurement has not been performed");
|
||||
|
@ -472,7 +467,7 @@ impl TextLayout {
|
|||
|
||||
/// Get the pixel position for the given byte index.
|
||||
pub fn position_for_index(&self, index: usize) -> Option<Point<Pixels>> {
|
||||
let element_state = self.lock();
|
||||
let element_state = self.0.borrow();
|
||||
let element_state = element_state
|
||||
.as_ref()
|
||||
.expect("measurement has not been performed");
|
||||
|
@ -503,7 +498,7 @@ impl TextLayout {
|
|||
|
||||
/// Retrieve the layout for the line containing the given byte index.
|
||||
pub fn line_layout_for_index(&self, index: usize) -> Option<Arc<WrappedLineLayout>> {
|
||||
let element_state = self.lock();
|
||||
let element_state = self.0.borrow();
|
||||
let element_state = element_state
|
||||
.as_ref()
|
||||
.expect("measurement has not been performed");
|
||||
|
@ -533,18 +528,18 @@ impl TextLayout {
|
|||
|
||||
/// The bounds of this layout.
|
||||
pub fn bounds(&self) -> Bounds<Pixels> {
|
||||
self.0.lock().as_ref().unwrap().bounds.unwrap()
|
||||
self.0.borrow().as_ref().unwrap().bounds.unwrap()
|
||||
}
|
||||
|
||||
/// The line height for this layout.
|
||||
pub fn line_height(&self) -> Pixels {
|
||||
self.0.lock().as_ref().unwrap().line_height
|
||||
self.0.borrow().as_ref().unwrap().line_height
|
||||
}
|
||||
|
||||
/// The text for this layout.
|
||||
pub fn text(&self) -> String {
|
||||
self.0
|
||||
.lock()
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.lines
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue