Merge remote-tracking branch 'origin/main' into cache

# Conflicts:
#	crates/gpui/src/elements/div.rs
This commit is contained in:
Antonio Scandurra
2024-01-15 11:37:46 +01:00
48 changed files with 600 additions and 903 deletions
-10
View File
@@ -355,16 +355,6 @@ impl Hsla {
}
}
// impl From<Hsla> for Rgba {
// fn from(value: Hsla) -> Self {
// let h = value.h;
// let s = value.s;
// let l = value.l;
// let c = (1 - |2L - 1|) X s
// }
// }
impl From<Rgba> for Hsla {
fn from(color: Rgba) -> Self {
let r = color.r;
+21 -16
View File
@@ -978,12 +978,31 @@ impl Interactivity {
f: impl FnOnce(&Style, Point<Pixels>, &mut WindowContext),
) {
let style = self.compute_style(Some(bounds), element_state, cx);
let z_index = style.z_index.unwrap_or(0);
let paint_hover_group_handler = |cx: &mut WindowContext| {
let hover_group_bounds = self
.group_hover_style
.as_ref()
.and_then(|group_hover| GroupBounds::get(&group_hover.group, cx));
if let Some(group_bounds) = hover_group_bounds {
let hovered = group_bounds.contains(&cx.mouse_position());
cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| {
if phase == DispatchPhase::Capture
&& group_bounds.contains(&event.position) != hovered
{
cx.refresh();
}
});
}
};
if style.visibility == Visibility::Hidden {
cx.with_z_index(z_index, |cx| paint_hover_group_handler(cx));
return;
}
let z_index = style.z_index.unwrap_or(0);
cx.with_z_index(z_index, |cx| {
style.paint(bounds, cx, |cx| {
cx.with_text_style(style.text_style().cloned(), |cx| {
@@ -1166,21 +1185,7 @@ impl Interactivity {
})
}
let hover_group_bounds = self
.group_hover_style
.as_ref()
.and_then(|group_hover| GroupBounds::get(&group_hover.group, cx));
if let Some(group_bounds) = hover_group_bounds {
let hovered = group_bounds.contains(&cx.mouse_position());
cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| {
if phase == DispatchPhase::Capture
&& group_bounds.contains(&event.position) != hovered
{
cx.refresh();
}
});
}
paint_hover_group_handler(cx);
if self.hover_style.is_some()
|| self.base_style.mouse_cursor.is_some()
+2
View File
@@ -43,6 +43,7 @@ pub enum ListAlignment {
pub struct ListScrollEvent {
pub visible_range: Range<usize>,
pub count: usize,
pub is_scrolled: bool,
}
#[derive(Clone)]
@@ -253,6 +254,7 @@ impl StateInner {
&ListScrollEvent {
visible_range,
count: self.items.summary().count,
is_scrolled: self.logical_scroll_top.is_some(),
},
cx,
);
+120 -112
View File
@@ -18,7 +18,7 @@ use smallvec::SmallVec;
use std::{ffi::c_void, mem, ptr, sync::Arc};
const SHADERS_METALLIB: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/shaders.metallib"));
const INSTANCE_BUFFER_SIZE: usize = 8192 * 1024; // This is an arbitrary decision. There's probably a more optimal value.
const INSTANCE_BUFFER_SIZE: usize = 32 * 1024 * 1024; // This is an arbitrary decision. There's probably a more optimal value (maybe even we could adjust dynamically...)
pub(crate) struct MetalRenderer {
layer: metal::MetalLayer,
@@ -204,7 +204,11 @@ impl MetalRenderer {
let command_buffer = command_queue.new_command_buffer();
let mut instance_offset = 0;
let path_tiles = self.rasterize_paths(scene.paths(), &mut instance_offset, command_buffer);
let Some(path_tiles) =
self.rasterize_paths(scene.paths(), &mut instance_offset, command_buffer)
else {
panic!("failed to rasterize {} paths", scene.paths().len());
};
let render_pass_descriptor = metal::RenderPassDescriptor::new();
let color_attachment = render_pass_descriptor
@@ -228,67 +232,67 @@ impl MetalRenderer {
zfar: 1.0,
});
for batch in scene.batches() {
match batch {
PrimitiveBatch::Shadows(shadows) => {
self.draw_shadows(
shadows,
&mut instance_offset,
viewport_size,
command_encoder,
);
}
let ok = match batch {
PrimitiveBatch::Shadows(shadows) => self.draw_shadows(
shadows,
&mut instance_offset,
viewport_size,
command_encoder,
),
PrimitiveBatch::Quads(quads) => {
self.draw_quads(quads, &mut instance_offset, viewport_size, command_encoder);
}
PrimitiveBatch::Paths(paths) => {
self.draw_paths(
paths,
&path_tiles,
&mut instance_offset,
viewport_size,
command_encoder,
);
}
PrimitiveBatch::Underlines(underlines) => {
self.draw_underlines(
underlines,
&mut instance_offset,
viewport_size,
command_encoder,
);
self.draw_quads(quads, &mut instance_offset, viewport_size, command_encoder)
}
PrimitiveBatch::Paths(paths) => self.draw_paths(
paths,
&path_tiles,
&mut instance_offset,
viewport_size,
command_encoder,
),
PrimitiveBatch::Underlines(underlines) => self.draw_underlines(
underlines,
&mut instance_offset,
viewport_size,
command_encoder,
),
PrimitiveBatch::MonochromeSprites {
texture_id,
sprites,
} => {
self.draw_monochrome_sprites(
texture_id,
sprites,
&mut instance_offset,
viewport_size,
command_encoder,
);
}
} => self.draw_monochrome_sprites(
texture_id,
sprites,
&mut instance_offset,
viewport_size,
command_encoder,
),
PrimitiveBatch::PolychromeSprites {
texture_id,
sprites,
} => {
self.draw_polychrome_sprites(
texture_id,
sprites,
&mut instance_offset,
viewport_size,
command_encoder,
);
}
PrimitiveBatch::Surfaces(surfaces) => {
self.draw_surfaces(
surfaces,
&mut instance_offset,
viewport_size,
command_encoder,
);
}
} => self.draw_polychrome_sprites(
texture_id,
sprites,
&mut instance_offset,
viewport_size,
command_encoder,
),
PrimitiveBatch::Surfaces(surfaces) => self.draw_surfaces(
surfaces,
&mut instance_offset,
viewport_size,
command_encoder,
),
};
if !ok {
panic!("scene too large: {} paths, {} shadows, {} quads, {} underlines, {} mono, {} poly, {} surfaces",
scene.paths.len(),
scene.shadows.len(),
scene.quads.len(),
scene.underlines.len(),
scene.monochrome_sprites.len(),
scene.polychrome_sprites.len(),
scene.surfaces.len(),
)
}
}
@@ -311,7 +315,7 @@ impl MetalRenderer {
paths: &[Path<ScaledPixels>],
offset: &mut usize,
command_buffer: &metal::CommandBufferRef,
) -> HashMap<PathId, AtlasTile> {
) -> Option<HashMap<PathId, AtlasTile>> {
let mut tiles = HashMap::default();
let mut vertices_by_texture_id = HashMap::default();
for path in paths {
@@ -337,10 +341,9 @@ impl MetalRenderer {
for (texture_id, vertices) in vertices_by_texture_id {
align_offset(offset);
let next_offset = *offset + vertices.len() * mem::size_of::<PathVertex<ScaledPixels>>();
assert!(
next_offset <= INSTANCE_BUFFER_SIZE,
"instance buffer exhausted"
);
if next_offset > INSTANCE_BUFFER_SIZE {
return None;
}
let render_pass_descriptor = metal::RenderPassDescriptor::new();
let color_attachment = render_pass_descriptor
@@ -389,7 +392,7 @@ impl MetalRenderer {
*offset = next_offset;
}
tiles
Some(tiles)
}
fn draw_shadows(
@@ -398,9 +401,9 @@ impl MetalRenderer {
offset: &mut usize,
viewport_size: Size<DevicePixels>,
command_encoder: &metal::RenderCommandEncoderRef,
) {
) -> bool {
if shadows.is_empty() {
return;
return true;
}
align_offset(offset);
@@ -429,6 +432,12 @@ impl MetalRenderer {
let shadow_bytes_len = std::mem::size_of_val(shadows);
let buffer_contents = unsafe { (self.instances.contents() as *mut u8).add(*offset) };
let next_offset = *offset + shadow_bytes_len;
if next_offset > INSTANCE_BUFFER_SIZE {
return false;
}
unsafe {
ptr::copy_nonoverlapping(
shadows.as_ptr() as *const u8,
@@ -437,12 +446,6 @@ impl MetalRenderer {
);
}
let next_offset = *offset + shadow_bytes_len;
assert!(
next_offset <= INSTANCE_BUFFER_SIZE,
"instance buffer exhausted"
);
command_encoder.draw_primitives_instanced(
metal::MTLPrimitiveType::Triangle,
0,
@@ -450,6 +453,7 @@ impl MetalRenderer {
shadows.len() as u64,
);
*offset = next_offset;
true
}
fn draw_quads(
@@ -458,9 +462,9 @@ impl MetalRenderer {
offset: &mut usize,
viewport_size: Size<DevicePixels>,
command_encoder: &metal::RenderCommandEncoderRef,
) {
) -> bool {
if quads.is_empty() {
return;
return true;
}
align_offset(offset);
@@ -489,16 +493,16 @@ impl MetalRenderer {
let quad_bytes_len = std::mem::size_of_val(quads);
let buffer_contents = unsafe { (self.instances.contents() as *mut u8).add(*offset) };
let next_offset = *offset + quad_bytes_len;
if next_offset > INSTANCE_BUFFER_SIZE {
return false;
}
unsafe {
ptr::copy_nonoverlapping(quads.as_ptr() as *const u8, buffer_contents, quad_bytes_len);
}
let next_offset = *offset + quad_bytes_len;
assert!(
next_offset <= INSTANCE_BUFFER_SIZE,
"instance buffer exhausted"
);
command_encoder.draw_primitives_instanced(
metal::MTLPrimitiveType::Triangle,
0,
@@ -506,6 +510,7 @@ impl MetalRenderer {
quads.len() as u64,
);
*offset = next_offset;
true
}
fn draw_paths(
@@ -515,9 +520,9 @@ impl MetalRenderer {
offset: &mut usize,
viewport_size: Size<DevicePixels>,
command_encoder: &metal::RenderCommandEncoderRef,
) {
) -> bool {
if paths.is_empty() {
return;
return true;
}
command_encoder.set_render_pipeline_state(&self.path_sprites_pipeline_state);
@@ -587,8 +592,14 @@ impl MetalRenderer {
.set_fragment_texture(SpriteInputIndex::AtlasTexture as u64, Some(&texture));
let sprite_bytes_len = mem::size_of::<MonochromeSprite>() * sprites.len();
let next_offset = *offset + sprite_bytes_len;
if next_offset > INSTANCE_BUFFER_SIZE {
return false;
}
let buffer_contents =
unsafe { (self.instances.contents() as *mut u8).add(*offset) };
unsafe {
ptr::copy_nonoverlapping(
sprites.as_ptr() as *const u8,
@@ -597,12 +608,6 @@ impl MetalRenderer {
);
}
let next_offset = *offset + sprite_bytes_len;
assert!(
next_offset <= INSTANCE_BUFFER_SIZE,
"instance buffer exhausted"
);
command_encoder.draw_primitives_instanced(
metal::MTLPrimitiveType::Triangle,
0,
@@ -613,6 +618,7 @@ impl MetalRenderer {
sprites.clear();
}
}
true
}
fn draw_underlines(
@@ -621,9 +627,9 @@ impl MetalRenderer {
offset: &mut usize,
viewport_size: Size<DevicePixels>,
command_encoder: &metal::RenderCommandEncoderRef,
) {
) -> bool {
if underlines.is_empty() {
return;
return true;
}
align_offset(offset);
@@ -661,10 +667,9 @@ impl MetalRenderer {
}
let next_offset = *offset + quad_bytes_len;
assert!(
next_offset <= INSTANCE_BUFFER_SIZE,
"instance buffer exhausted"
);
if next_offset > INSTANCE_BUFFER_SIZE {
return false;
}
command_encoder.draw_primitives_instanced(
metal::MTLPrimitiveType::Triangle,
@@ -673,6 +678,7 @@ impl MetalRenderer {
underlines.len() as u64,
);
*offset = next_offset;
true
}
fn draw_monochrome_sprites(
@@ -682,9 +688,9 @@ impl MetalRenderer {
offset: &mut usize,
viewport_size: Size<DevicePixels>,
command_encoder: &metal::RenderCommandEncoderRef,
) {
) -> bool {
if sprites.is_empty() {
return;
return true;
}
align_offset(offset);
@@ -723,6 +729,12 @@ impl MetalRenderer {
let sprite_bytes_len = std::mem::size_of_val(sprites);
let buffer_contents = unsafe { (self.instances.contents() as *mut u8).add(*offset) };
let next_offset = *offset + sprite_bytes_len;
if next_offset > INSTANCE_BUFFER_SIZE {
return false;
}
unsafe {
ptr::copy_nonoverlapping(
sprites.as_ptr() as *const u8,
@@ -731,12 +743,6 @@ impl MetalRenderer {
);
}
let next_offset = *offset + sprite_bytes_len;
assert!(
next_offset <= INSTANCE_BUFFER_SIZE,
"instance buffer exhausted"
);
command_encoder.draw_primitives_instanced(
metal::MTLPrimitiveType::Triangle,
0,
@@ -744,6 +750,7 @@ impl MetalRenderer {
sprites.len() as u64,
);
*offset = next_offset;
true
}
fn draw_polychrome_sprites(
@@ -753,9 +760,9 @@ impl MetalRenderer {
offset: &mut usize,
viewport_size: Size<DevicePixels>,
command_encoder: &metal::RenderCommandEncoderRef,
) {
) -> bool {
if sprites.is_empty() {
return;
return true;
}
align_offset(offset);
@@ -794,6 +801,12 @@ impl MetalRenderer {
let sprite_bytes_len = std::mem::size_of_val(sprites);
let buffer_contents = unsafe { (self.instances.contents() as *mut u8).add(*offset) };
let next_offset = *offset + sprite_bytes_len;
if next_offset > INSTANCE_BUFFER_SIZE {
return false;
}
unsafe {
ptr::copy_nonoverlapping(
sprites.as_ptr() as *const u8,
@@ -802,12 +815,6 @@ impl MetalRenderer {
);
}
let next_offset = *offset + sprite_bytes_len;
assert!(
next_offset <= INSTANCE_BUFFER_SIZE,
"instance buffer exhausted"
);
command_encoder.draw_primitives_instanced(
metal::MTLPrimitiveType::Triangle,
0,
@@ -815,6 +822,7 @@ impl MetalRenderer {
sprites.len() as u64,
);
*offset = next_offset;
true
}
fn draw_surfaces(
@@ -823,7 +831,7 @@ impl MetalRenderer {
offset: &mut usize,
viewport_size: Size<DevicePixels>,
command_encoder: &metal::RenderCommandEncoderRef,
) {
) -> bool {
command_encoder.set_render_pipeline_state(&self.surfaces_pipeline_state);
command_encoder.set_vertex_buffer(
SurfaceInputIndex::Vertices as u64,
@@ -874,10 +882,9 @@ impl MetalRenderer {
align_offset(offset);
let next_offset = *offset + mem::size_of::<Surface>();
assert!(
next_offset <= INSTANCE_BUFFER_SIZE,
"instance buffer exhausted"
);
if next_offset > INSTANCE_BUFFER_SIZE {
return false;
}
command_encoder.set_vertex_buffer(
SurfaceInputIndex::Surfaces as u64,
@@ -913,6 +920,7 @@ impl MetalRenderer {
command_encoder.draw_primitives(metal::MTLPrimitiveType::Triangle, 0, 6);
*offset = next_offset;
}
true
}
}
+7 -7
View File
@@ -41,13 +41,13 @@ impl From<ViewId> for EntityId {
pub struct Scene {
layers_by_order: BTreeMap<StackingOrder, LayerId>,
orders_by_layer: BTreeMap<LayerId, StackingOrder>,
shadows: Vec<Shadow>,
quads: Vec<Quad>,
paths: Vec<Path<ScaledPixels>>,
underlines: Vec<Underline>,
monochrome_sprites: Vec<MonochromeSprite>,
polychrome_sprites: Vec<PolychromeSprite>,
surfaces: Vec<Surface>,
pub(crate) shadows: Vec<Shadow>,
pub(crate) quads: Vec<Quad>,
pub(crate) paths: Vec<Path<ScaledPixels>>,
pub(crate) underlines: Vec<Underline>,
pub(crate) monochrome_sprites: Vec<MonochromeSprite>,
pub(crate) polychrome_sprites: Vec<PolychromeSprite>,
pub(crate) surfaces: Vec<Surface>,
}
impl Scene {
+48 -48
View File
@@ -1,10 +1,10 @@
use std::{iter, mem, ops::Range};
use crate::{
black, phi, point, quad, rems, AbsoluteLength, BorrowWindow, Bounds, ContentMask, Corners,
CornersRefinement, CursorStyle, DefiniteLength, Edges, EdgesRefinement, Font, FontFeatures,
FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rgba, SharedString, Size,
SizeRefinement, Styled, TextRun, WindowContext,
black, phi, point, quad, rems, AbsoluteLength, BorrowAppContext, BorrowWindow, Bounds,
ContentMask, Corners, CornersRefinement, CursorStyle, DefiniteLength, Edges, EdgesRefinement,
Font, FontFeatures, FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rgba,
SharedString, Size, SizeRefinement, Styled, TextRun, WindowContext,
};
use collections::HashSet;
use refineable::{Cascade, Refineable};
@@ -308,54 +308,54 @@ impl Style {
}
}
// pub fn apply_text_style<C, F, R>(&self, cx: &mut C, f: F) -> R
// where
// C: BorrowAppContext,
// F: FnOnce(&mut C) -> R,
// {
// if self.text.is_some() {
// cx.with_text_style(Some(self.text.clone()), f)
// } else {
// f(cx)
// }
// }
pub fn apply_text_style<C, F, R>(&self, cx: &mut C, f: F) -> R
where
C: BorrowAppContext,
F: FnOnce(&mut C) -> R,
{
if self.text.is_some() {
cx.with_text_style(Some(self.text.clone()), f)
} else {
f(cx)
}
}
// /// Apply overflow to content mask
// pub fn apply_overflow<C, F, R>(&self, bounds: Bounds<Pixels>, cx: &mut C, f: F) -> R
// where
// C: BorrowWindow,
// F: FnOnce(&mut C) -> R,
// {
// let current_mask = cx.content_mask();
/// Apply overflow to content mask
pub fn apply_overflow<C, F, R>(&self, bounds: Bounds<Pixels>, cx: &mut C, f: F) -> R
where
C: BorrowWindow,
F: FnOnce(&mut C) -> R,
{
let current_mask = cx.content_mask();
// let min = current_mask.bounds.origin;
// let max = current_mask.bounds.lower_right();
let min = current_mask.bounds.origin;
let max = current_mask.bounds.lower_right();
// let mask_bounds = match (
// self.overflow.x == Overflow::Visible,
// self.overflow.y == Overflow::Visible,
// ) {
// // x and y both visible
// (true, true) => return f(cx),
// // x visible, y hidden
// (true, false) => Bounds::from_corners(
// point(min.x, bounds.origin.y),
// point(max.x, bounds.lower_right().y),
// ),
// // x hidden, y visible
// (false, true) => Bounds::from_corners(
// point(bounds.origin.x, min.y),
// point(bounds.lower_right().x, max.y),
// ),
// // both hidden
// (false, false) => bounds,
// };
// let mask = ContentMask {
// bounds: mask_bounds,
// };
let mask_bounds = match (
self.overflow.x == Overflow::Visible,
self.overflow.y == Overflow::Visible,
) {
// x and y both visible
(true, true) => return f(cx),
// x visible, y hidden
(true, false) => Bounds::from_corners(
point(min.x, bounds.origin.y),
point(max.x, bounds.lower_right().y),
),
// x hidden, y visible
(false, true) => Bounds::from_corners(
point(bounds.origin.x, min.y),
point(bounds.lower_right().x, max.y),
),
// both hidden
(false, false) => bounds,
};
let mask = ContentMask {
bounds: mask_bounds,
};
// cx.with_content_mask(Some(mask), f)
// }
cx.with_content_mask(Some(mask), f)
}
/// Paints the background of an element styled with this style.
pub fn paint(
+9 -2
View File
@@ -1,7 +1,7 @@
use crate::{
self as gpui, hsla, point, px, relative, rems, AbsoluteLength, AlignItems, CursorStyle,
DefiniteLength, Display, Fill, FlexDirection, Hsla, JustifyContent, Length, Position,
SharedString, StyleRefinement, Visibility, WhiteSpace,
DefiniteLength, Display, Fill, FlexDirection, FontWeight, Hsla, JustifyContent, Length,
Position, SharedString, StyleRefinement, Visibility, WhiteSpace,
};
use crate::{BoxShadow, TextStyleRefinement};
use smallvec::{smallvec, SmallVec};
@@ -494,6 +494,13 @@ pub trait Styled: Sized {
self
}
fn font_weight(mut self, weight: FontWeight) -> Self {
self.text_style()
.get_or_insert_with(Default::default)
.font_weight = Some(weight);
self
}
fn text_bg(mut self, bg: impl Into<Hsla>) -> Self {
self.text_style()
.get_or_insert_with(Default::default)
-14
View File
@@ -275,20 +275,6 @@ impl ToTaffy<taffy::style::Style> for Style {
}
}
// impl ToTaffy for Bounds<Length> {
// type Output = taffy::prelude::Bounds<taffy::prelude::LengthPercentageAuto>;
// fn to_taffy(
// &self,
// rem_size: Pixels,
// ) -> taffy::prelude::Bounds<taffy::prelude::LengthPercentageAuto> {
// taffy::prelude::Bounds {
// origin: self.origin.to_taffy(rem_size),
// size: self.size.to_taffy(rem_size),
// }
// }
// }
impl ToTaffy<taffy::style::LengthPercentageAuto> for Length {
fn to_taffy(&self, rem_size: Pixels) -> taffy::prelude::LengthPercentageAuto {
match self {
+1 -1
View File
@@ -59,7 +59,7 @@ impl TextSystem {
fallback_font_stack: smallvec![
// TODO: This is currently Zed-specific.
// We should allow GPUI users to provide their own fallback font stack.
font("Zed Mono"),
font("Zed Sans"),
font("Helvetica")
],
}
-7
View File
@@ -3319,13 +3319,6 @@ impl AnyWindowHandle {
}
}
// #[cfg(any(test, feature = "test-support"))]
// impl From<SmallVec<[u32; 16]>> for StackingOrder {
// fn from(small_vec: SmallVec<[u32; 16]>) -> Self {
// StackingOrder(small_vec)
// }
// }
/// An identifier for an [`Element`](crate::Element).
///
/// Can be constructed with a string, a number, or both, as well