Checkpoint

This commit is contained in:
Antonio Scandurra 2023-10-09 18:50:42 +02:00
parent 6a4c2a0d40
commit d889cdecde
8 changed files with 484 additions and 279 deletions

View file

@ -1,15 +1,17 @@
use crate::{
image_cache::RenderImageParams, px, size, AnyView, AppContext, AsyncWindowContext,
AvailableSpace, BorrowAppContext, Bounds, Context, Corners, DevicePixels, DisplayId, Effect,
Element, EntityId, FontId, GlyphId, Handle, Hsla, ImageData, IsZero, LayoutId, MainThread,
MainThreadOnly, MonochromeSprite, Pixels, PlatformAtlas, PlatformWindow, Point,
PolychromeSprite, Reference, RenderGlyphParams, RenderSvgParams, ScaledPixels, Scene,
SharedString, Size, StackingOrder, Style, TaffyLayoutEngine, Task, Underline, UnderlineStyle,
WeakHandle, WindowOptions, SUBPIXEL_VARIANTS,
AvailableSpace, BorrowAppContext, Bounds, BoxShadow, Context, Corners, DevicePixels, DisplayId,
Edges, Effect, Element, EntityId, FontId, GlyphId, Handle, Hsla, ImageData, IsZero, LayoutId,
MainThread, MainThreadOnly, MonochromeSprite, Path, Pixels, PlatformAtlas, PlatformWindow,
Point, PolychromeSprite, Quad, Reference, RenderGlyphParams, RenderSvgParams, ScaledPixels,
SceneBuilder, Shadow, SharedString, Size, StackingOrder, Style, TaffyLayoutEngine, Task,
Underline, UnderlineStyle, WeakHandle, WindowOptions, SUBPIXEL_VARIANTS,
};
use anyhow::Result;
use smallvec::SmallVec;
use std::{any::TypeId, borrow::Cow, future::Future, marker::PhantomData, mem, sync::Arc};
use std::{
any::TypeId, borrow::Cow, fmt::Debug, future::Future, marker::PhantomData, mem, sync::Arc,
};
use util::ResultExt;
pub struct AnyWindow {}
@ -25,8 +27,9 @@ pub struct Window {
pub(crate) root_view: Option<AnyView<()>>,
mouse_position: Point<Pixels>,
current_stacking_order: StackingOrder,
content_mask_stack: Vec<ContentMask>,
pub(crate) scene: Scene,
content_mask_stack: Vec<ContentMask<Pixels>>,
scale_factor: f32,
pub(crate) scene_builder: SceneBuilder,
pub(crate) dirty: bool,
}
@ -47,7 +50,8 @@ impl Window {
let cx = cx.to_async();
move |content_size, scale_factor| {
cx.update_window(handle, |cx| {
cx.window.scene = Scene::new(scale_factor);
cx.window.scale_factor = scale_factor;
cx.window.scene_builder = SceneBuilder::new();
cx.window.content_size = content_size;
cx.window.display_id = cx
.window
@ -75,20 +79,22 @@ impl Window {
mouse_position,
current_stacking_order: SmallVec::new(),
content_mask_stack: Vec::new(),
scene: Scene::new(scale_factor),
scale_factor,
scene_builder: SceneBuilder::new(),
dirty: true,
}
}
}
#[derive(Clone, Debug)]
pub struct ContentMask {
pub bounds: Bounds<Pixels>,
#[derive(Clone, Debug, Default, PartialEq, Eq)]
#[repr(C)]
pub struct ContentMask<P: Clone + Debug> {
pub bounds: Bounds<P>,
}
impl ContentMask {
pub fn scale(&self, factor: f32) -> ScaledContentMask {
ScaledContentMask {
impl ContentMask<Pixels> {
pub fn scale(&self, factor: f32) -> ContentMask<ScaledPixels> {
ContentMask {
bounds: self.bounds.scale(factor),
}
}
@ -99,12 +105,6 @@ impl ContentMask {
}
}
#[derive(Default, Clone, Debug, PartialEq, Eq)]
#[repr(C)]
pub struct ScaledContentMask {
bounds: Bounds<ScaledPixels>,
}
pub struct WindowContext<'a, 'w> {
app: Reference<'a, AppContext>,
window: Reference<'w, Window>,
@ -234,7 +234,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
}
pub fn scale_factor(&self) -> f32 {
self.window.scene.scale_factor
self.window.scale_factor
}
pub fn rem_size(&self) -> Pixels {
@ -245,10 +245,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
self.window.mouse_position
}
pub fn scene(&mut self) -> &mut Scene {
&mut self.window.scene
}
pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
self.window.current_stacking_order.push(order);
let result = f(self);
@ -256,8 +252,69 @@ impl<'a, 'w> WindowContext<'a, 'w> {
result
}
pub fn current_stacking_order(&self) -> StackingOrder {
self.window.current_stacking_order.clone()
pub fn paint_shadows(
&mut self,
bounds: Bounds<Pixels>,
corner_radii: Corners<Pixels>,
shadows: &[BoxShadow],
) {
let scale_factor = self.scale_factor();
let content_mask = self.content_mask();
let window = &mut *self.window;
for shadow in shadows {
let mut shadow_bounds = bounds;
shadow_bounds.origin += shadow.offset;
shadow_bounds.dilate(shadow.spread_radius);
window.scene_builder.insert(
&window.current_stacking_order,
Shadow {
order: 0,
bounds: shadow_bounds.scale(scale_factor),
content_mask: content_mask.scale(scale_factor),
corner_radii: corner_radii.scale(scale_factor),
color: shadow.color,
blur_radius: shadow.blur_radius.scale(scale_factor),
},
);
}
}
pub fn paint_quad(
&mut self,
bounds: Bounds<Pixels>,
corner_radii: Corners<Pixels>,
background: impl Into<Hsla>,
border_widths: Edges<Pixels>,
border_color: impl Into<Hsla>,
) {
let scale_factor = self.scale_factor();
let content_mask = self.content_mask();
let window = &mut *self.window;
window.scene_builder.insert(
&window.current_stacking_order,
Quad {
order: 0,
bounds: bounds.scale(scale_factor),
content_mask: content_mask.scale(scale_factor),
background: background.into(),
border_color: border_color.into(),
corner_radii: corner_radii.scale(scale_factor),
border_widths: border_widths.scale(scale_factor),
},
);
}
pub fn paint_path(&mut self, mut path: Path<Pixels>) {
let scale_factor = self.scale_factor();
let content_mask = self.content_mask();
for vertex in &mut path.vertices {
vertex.content_mask = content_mask.clone();
}
let window = &mut *self.window;
window
.scene_builder
.insert(&window.current_stacking_order, path.scale(scale_factor));
}
pub fn paint_underline(
@ -277,9 +334,9 @@ impl<'a, 'w> WindowContext<'a, 'w> {
size: size(width, height),
};
let content_mask = self.content_mask();
let layer_id = self.current_stacking_order();
self.window.scene.insert(
layer_id,
let window = &mut *self.window;
window.scene_builder.insert(
&window.current_stacking_order,
Underline {
order: 0,
bounds: bounds.scale(scale_factor),
@ -317,7 +374,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
let raster_bounds = self.text_system().raster_bounds(&params)?;
if !raster_bounds.is_zero() {
let layer_id = self.current_stacking_order();
let tile =
self.window
.sprite_atlas
@ -330,9 +386,9 @@ impl<'a, 'w> WindowContext<'a, 'w> {
size: tile.bounds.size.map(Into::into),
};
let content_mask = self.content_mask().scale(scale_factor);
self.window.scene.insert(
layer_id,
let window = &mut *self.window;
window.scene_builder.insert(
&window.current_stacking_order,
MonochromeSprite {
order: 0,
bounds,
@ -366,7 +422,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
let raster_bounds = self.text_system().raster_bounds(&params)?;
if !raster_bounds.is_zero() {
let layer_id = self.current_stacking_order();
let tile =
self.window
.sprite_atlas
@ -379,9 +434,10 @@ impl<'a, 'w> WindowContext<'a, 'w> {
size: tile.bounds.size.map(Into::into),
};
let content_mask = self.content_mask().scale(scale_factor);
let window = &mut *self.window;
self.window.scene.insert(
layer_id,
window.scene_builder.insert(
&window.current_stacking_order,
PolychromeSprite {
order: 0,
bounds,
@ -411,7 +467,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
.map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
};
let layer_id = self.current_stacking_order();
let tile =
self.window
.sprite_atlas
@ -421,8 +476,9 @@ impl<'a, 'w> WindowContext<'a, 'w> {
})?;
let content_mask = self.content_mask().scale(scale_factor);
self.window.scene.insert(
layer_id,
let window = &mut *self.window;
window.scene_builder.insert(
&window.current_stacking_order,
MonochromeSprite {
order: 0,
bounds,
@ -446,7 +502,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
let bounds = bounds.scale(scale_factor);
let params = RenderImageParams { image_id: data.id };
let order = self.current_stacking_order();
let tile = self
.window
.sprite_atlas
@ -456,8 +511,9 @@ impl<'a, 'w> WindowContext<'a, 'w> {
let content_mask = self.content_mask().scale(scale_factor);
let corner_radii = corner_radii.scale(scale_factor);
self.window.scene.insert(
order,
let window = &mut *self.window;
window.scene_builder.insert(
&window.current_stacking_order,
PolychromeSprite {
order: 0,
bounds,
@ -467,7 +523,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
grayscale,
},
);
Ok(())
}
@ -485,7 +540,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
root_view.paint(layout, &mut (), &mut frame_state, cx)?;
cx.window.root_view = Some(root_view);
let scene = cx.window.scene.take();
let scene = cx.window.scene_builder.build();
cx.run_on_main(view, |_, cx| {
cx.window
@ -557,7 +612,11 @@ pub trait BorrowWindow: BorrowAppContext {
fn window(&self) -> &Window;
fn window_mut(&mut self) -> &mut Window;
fn with_content_mask<R>(&mut self, mask: ContentMask, f: impl FnOnce(&mut Self) -> R) -> R {
fn with_content_mask<R>(
&mut self,
mask: ContentMask<Pixels>,
f: impl FnOnce(&mut Self) -> R,
) -> R {
let mask = mask.intersect(&self.content_mask());
self.window_mut().content_mask_stack.push(mask);
let result = f(self);
@ -565,7 +624,7 @@ pub trait BorrowWindow: BorrowAppContext {
result
}
fn content_mask(&self) -> ContentMask {
fn content_mask(&self) -> ContentMask<Pixels> {
self.window()
.content_mask_stack
.last()