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,
|
WrappedLineLayout,
|
||||||
};
|
};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use parking_lot::{Mutex, MutexGuard};
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::{
|
use std::{
|
||||||
cell::{Cell, RefCell},
|
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.
|
/// The Layout for TextElement. This can be used to map indices to pixels and vice versa.
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct TextLayout(Arc<Mutex<Option<TextLayoutInner>>>);
|
pub struct TextLayout(Rc<RefCell<Option<TextLayoutInner>>>);
|
||||||
|
|
||||||
struct TextLayoutInner {
|
struct TextLayoutInner {
|
||||||
lines: SmallVec<[WrappedLine; 1]>,
|
lines: SmallVec<[WrappedLine; 1]>,
|
||||||
|
@ -288,10 +287,6 @@ struct TextLayoutInner {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextLayout {
|
impl TextLayout {
|
||||||
fn lock(&self) -> MutexGuard<Option<TextLayoutInner>> {
|
|
||||||
self.0.lock()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&self,
|
&self,
|
||||||
text: SharedString,
|
text: SharedString,
|
||||||
|
@ -341,7 +336,7 @@ impl TextLayout {
|
||||||
(None, None)
|
(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()
|
if text_layout.size.is_some()
|
||||||
&& (wrap_width.is_none() || wrap_width == text_layout.wrap_width)
|
&& (wrap_width.is_none() || wrap_width == text_layout.wrap_width)
|
||||||
{
|
{
|
||||||
|
@ -367,7 +362,7 @@ impl TextLayout {
|
||||||
)
|
)
|
||||||
.log_err()
|
.log_err()
|
||||||
else {
|
else {
|
||||||
element_state.lock().replace(TextLayoutInner {
|
element_state.0.borrow_mut().replace(TextLayoutInner {
|
||||||
lines: Default::default(),
|
lines: Default::default(),
|
||||||
line_height,
|
line_height,
|
||||||
wrap_width,
|
wrap_width,
|
||||||
|
@ -384,7 +379,7 @@ impl TextLayout {
|
||||||
size.width = size.width.max(line_size.width).ceil();
|
size.width = size.width.max(line_size.width).ceil();
|
||||||
}
|
}
|
||||||
|
|
||||||
element_state.lock().replace(TextLayoutInner {
|
element_state.0.borrow_mut().replace(TextLayoutInner {
|
||||||
lines,
|
lines,
|
||||||
line_height,
|
line_height,
|
||||||
wrap_width,
|
wrap_width,
|
||||||
|
@ -400,7 +395,7 @@ impl TextLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepaint(&self, bounds: Bounds<Pixels>, text: &str) {
|
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
|
let element_state = element_state
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.ok_or_else(|| anyhow!("measurement has not been performed on {}", text))
|
.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) {
|
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
|
let element_state = element_state
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or_else(|| anyhow!("measurement has not been performed on {}", text))
|
.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.
|
/// Get the byte index into the input of the pixel position.
|
||||||
pub fn index_for_position(&self, mut position: Point<Pixels>) -> Result<usize, usize> {
|
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
|
let element_state = element_state
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.expect("measurement has not been performed");
|
.expect("measurement has not been performed");
|
||||||
|
@ -472,7 +467,7 @@ impl TextLayout {
|
||||||
|
|
||||||
/// Get the pixel position for the given byte index.
|
/// Get the pixel position for the given byte index.
|
||||||
pub fn position_for_index(&self, index: usize) -> Option<Point<Pixels>> {
|
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
|
let element_state = element_state
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.expect("measurement has not been performed");
|
.expect("measurement has not been performed");
|
||||||
|
@ -503,7 +498,7 @@ impl TextLayout {
|
||||||
|
|
||||||
/// Retrieve the layout for the line containing the given byte index.
|
/// Retrieve the layout for the line containing the given byte index.
|
||||||
pub fn line_layout_for_index(&self, index: usize) -> Option<Arc<WrappedLineLayout>> {
|
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
|
let element_state = element_state
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.expect("measurement has not been performed");
|
.expect("measurement has not been performed");
|
||||||
|
@ -533,18 +528,18 @@ impl TextLayout {
|
||||||
|
|
||||||
/// The bounds of this layout.
|
/// The bounds of this layout.
|
||||||
pub fn bounds(&self) -> Bounds<Pixels> {
|
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.
|
/// The line height for this layout.
|
||||||
pub fn line_height(&self) -> Pixels {
|
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.
|
/// The text for this layout.
|
||||||
pub fn text(&self) -> String {
|
pub fn text(&self) -> String {
|
||||||
self.0
|
self.0
|
||||||
.lock()
|
.borrow()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.lines
|
.lines
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue