Detailed changes
@@ -2,7 +2,7 @@ use bytemuck::{Pod, Zeroable};
use core::fmt::Debug;
use derive_more::{Add, AddAssign, Div, Mul, Sub, SubAssign};
use refineable::Refineable;
-use std::ops::{Add, AddAssign, Mul, Sub, SubAssign};
+use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};
#[derive(
Refineable, Default, Add, AddAssign, Sub, SubAssign, Mul, Div, Copy, Debug, PartialEq, Eq, Hash,
@@ -31,6 +31,13 @@ impl<T: Clone + Debug> Point<T> {
}
}
+impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Point<T> {
+ fn mul_assign(&mut self, rhs: S) {
+ self.x = self.x.clone() * rhs.clone();
+ self.y = self.y.clone() * rhs;
+ }
+}
+
impl<T: Clone + Debug + Sub<Output = T>> SubAssign<Size<T>> for Point<T> {
fn sub_assign(&mut self, rhs: Size<T>) {
self.x = self.x.clone() - rhs.width;
@@ -98,6 +105,13 @@ impl<T: Clone + Debug> Size<T> {
}
}
+impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Size<T> {
+ fn mul_assign(&mut self, rhs: S) {
+ self.width = self.width.clone() * rhs.clone();
+ self.height = self.height.clone() * rhs;
+ }
+}
+
impl From<Size<Option<Pixels>>> for Size<Option<f32>> {
fn from(val: Size<Option<Pixels>>) -> Self {
Size {
@@ -145,28 +159,28 @@ pub struct Bounds<T: Clone + Debug> {
unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Bounds<T> {}
unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Bounds<T> {}
-impl<T: Clone + Debug + Copy + Add<T, Output = T>> Bounds<T> {
+impl<T: Clone + Debug + Add<T, Output = T>> Bounds<T> {
pub fn upper_right(&self) -> Point<T> {
Point {
- x: self.origin.x + self.size.width,
- y: self.origin.y,
+ x: self.origin.x.clone() + self.size.width.clone(),
+ y: self.origin.y.clone(),
}
}
pub fn lower_right(&self) -> Point<T> {
Point {
- x: self.origin.x + self.size.width,
- y: self.origin.y + self.size.height,
+ x: self.origin.x.clone() + self.size.width.clone(),
+ y: self.origin.y.clone() + self.size.height.clone(),
}
}
}
-impl<T: Clone + Debug + Copy + PartialOrd + Add<T, Output = T>> Bounds<T> {
+impl<T: Clone + Debug + PartialOrd + Add<T, Output = T>> Bounds<T> {
pub fn contains_point(&self, point: Point<T>) -> bool {
point.x >= self.origin.x
- && point.x <= self.origin.x + self.size.width
+ && point.x <= self.origin.x.clone() + self.size.width.clone()
&& point.y >= self.origin.y
- && point.y <= self.origin.y + self.size.height
+ && point.y <= self.origin.y.clone() + self.size.height.clone()
}
}
@@ -182,6 +196,15 @@ pub struct Edges<T: Clone + Debug> {
pub left: T,
}
+impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Edges<T> {
+ fn mul_assign(&mut self, rhs: S) {
+ self.top = self.top.clone() * rhs.clone();
+ self.right = self.right.clone() * rhs.clone();
+ self.bottom = self.bottom.clone() * rhs.clone();
+ self.left = self.left.clone() * rhs.clone();
+ }
+}
+
impl<T: Clone + Debug + Copy> Copy for Edges<T> {}
unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Edges<T> {}
@@ -255,6 +278,15 @@ pub struct Corners<T: Clone + Debug> {
pub bottom_left: T,
}
+impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Corners<T> {
+ fn mul_assign(&mut self, rhs: S) {
+ self.top_left = self.top_left.clone() * rhs.clone();
+ self.top_right = self.top_right.clone() * rhs.clone();
+ self.bottom_right = self.bottom_right.clone() * rhs.clone();
+ self.bottom_left = self.bottom_left.clone() * rhs;
+ }
+}
+
impl<T: Clone + Debug + Copy> Copy for Corners<T> {}
unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Corners<T> {}
@@ -265,6 +297,14 @@ unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Corners<T> {}
#[repr(transparent)]
pub struct Pixels(pub(crate) f32);
+impl Mul<f32> for Pixels {
+ type Output = Pixels;
+
+ fn mul(self, other: f32) -> Pixels {
+ Pixels(self.0 * other)
+ }
+}
+
#[derive(
Clone, Copy, Debug, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd,
)]
@@ -287,14 +327,6 @@ impl Pixels {
}
}
-impl Mul<f32> for Pixels {
- type Output = Pixels;
-
- fn mul(self, other: f32) -> Pixels {
- Pixels(self.0 * other)
- }
-}
-
impl Mul<Pixels> for Pixels {
type Output = Pixels;
@@ -99,7 +99,7 @@ impl MetalRenderer {
&*self.layer
}
- pub fn draw(&mut self, scene: &Scene, scale_factor: f32) {
+ pub fn draw(&mut self, scene: &Scene) {
let layer = self.layer.clone();
let viewport_size = layer.drawable_size();
let viewport_size: Size<Pixels> =
@@ -140,7 +140,6 @@ impl MetalRenderer {
self.draw_quads(
&scene.opaque_primitives().quads,
&mut buffer_offset,
- scale_factor,
viewport_size,
scene.max_order(),
command_encoder,
@@ -161,7 +160,6 @@ impl MetalRenderer {
&mut self,
quads: &[Quad],
offset: &mut usize,
- scale_factor: f32,
viewport_size: Size<Pixels>,
max_order: u32,
command_encoder: &metal::RenderCommandEncoderRef,
@@ -184,7 +182,6 @@ impl MetalRenderer {
);
let quad_uniforms = QuadUniforms {
viewport_size,
- scale_factor,
max_order,
};
@@ -268,6 +265,5 @@ enum QuadInputIndex {
#[repr(C)]
pub(crate) struct QuadUniforms {
viewport_size: Size<Pixels>,
- scale_factor: f32,
max_order: u32,
}
@@ -35,9 +35,13 @@ vertex QuadVertexOutput quad_vertex(
};
}
-fragment float4 quad_fragment(QuadVertexOutput input [[stage_in]], constant Quad *quads [[buffer(QuadInputIndex_Quads)]]) {
+fragment float4 quad_fragment(
+ QuadVertexOutput input [[stage_in]],
+ constant Quad *quads [[buffer(QuadInputIndex_Quads)]],
+ constant QuadUniforms *uniforms [[buffer(QuadInputIndex_Uniforms)]]
+) {
Quad quad = quads[input.quad_id];
- float2 half_size = float2( quad.bounds.size.width, quad.bounds.size.height ) / 2.;
+ float2 half_size = float2(quad.bounds.size.width, quad.bounds.size.height) / 2.;
float2 center = float2( quad.bounds.origin.x, quad.bounds.origin.y ) + half_size;
float2 center_to_point = input.position.xy - center;
float corner_radius;
@@ -142,58 +146,3 @@ float4 hsla_to_rgba(Hsla hsla) {
float4 to_device_position(float2 pixel_position, uint order, uint max_order, float2 viewport_size) {
return float4(pixel_position / viewport_size * float2(2., -2.) + float2(-1., 1.), (1. - order / max_order), 1.);
}
-
-// fragment float4 quad_fragment(QuadVertexOutput input [[stage_in]]) {
-// float2 half_size = input.size / 2.;
-// float2 center = input.origin + half_size;
-// float2 center_to_point = input.position.xy - center;
-// float corner_radius;
-// if (center_to_point.x < 0.) {
-// if (center_to_point.y < 0.) {
-// corner_radius = input.corner_radius_top_left;
-// } else {
-// corner_radius = input.corner_radius_bottom_left;
-// }
-// } else {
-// if (center_to_point.y < 0.) {
-// corner_radius = input.corner_radius_top_right;
-// } else {
-// corner_radius = input.corner_radius_bottom_right;
-// }
-// }
-
-// float2 rounded_edge_to_point = fabs(center_to_point) - half_size + corner_radius;
-// float distance = length(max(0., rounded_edge_to_point)) + min(0., max(rounded_edge_to_point.x, rounded_edge_to_point.y)) - corner_radius;
-
-// float vertical_border = center_to_point.x <= 0. ? input.border_left : input.border_right;
-// float horizontal_border = center_to_point.y <= 0. ? input.border_top : input.border_bottom;
-// float2 inset_size = half_size - corner_radius - float2(vertical_border, horizontal_border);
-// float2 point_to_inset_corner = fabs(center_to_point) - inset_size;
-// float border_width;
-// if (point_to_inset_corner.x < 0. && point_to_inset_corner.y < 0.) {
-// border_width = 0.;
-// } else if (point_to_inset_corner.y > point_to_inset_corner.x) {
-// border_width = horizontal_border;
-// } else {
-// border_width = vertical_border;
-// }
-
-// float4 color;
-// if (border_width == 0.) {
-// color = input.background_color;
-// } else {
-// float inset_distance = distance + border_width;
-
-// // Decrease border's opacity as we move inside the background.
-// input.border_color.a *= 1. - saturate(0.5 - inset_distance);
-
-// // Alpha-blend the border and the background.
-// float output_alpha = input.border_color.a + input.background_color.a * (1. - input.border_color.a);
-// float3 premultiplied_border_rgb = input.border_color.rgb * input.border_color.a;
-// float3 premultiplied_background_rgb = input.background_color.rgb * input.background_color.a;
-// float3 premultiplied_output_rgb = premultiplied_border_rgb + premultiplied_background_rgb * (1. - input.border_color.a);
-// color = float4(premultiplied_output_rgb / output_alpha, output_alpha);
-// }
-
-// return color * float4(1., 1., 1., saturate(0.5 - distance));
-// }
@@ -1348,7 +1348,8 @@ extern "C" fn display_layer(this: &Object, _: Sel, _: id) {
let window_state = get_window_state(this);
let mut window_state = window_state.as_ref().lock();
- let mut scene = crate::Scene::new();
+ let scale_factor = window_state.scale_factor();
+ let mut scene = crate::Scene::new(scale_factor);
scene.insert(crate::Quad {
order: 0,
bounds: Bounds {
@@ -1366,8 +1367,7 @@ extern "C" fn display_layer(this: &Object, _: Sel, _: id) {
border_widths: Default::default(),
});
dbg!("!!!!!!!!!");
- let scale_factor = window_state.scale_factor();
- window_state.renderer.draw(&scene, scale_factor);
+ window_state.renderer.draw(&scene);
}
}
@@ -13,25 +13,26 @@ pub struct Scene {
transparent_primitives: slotmap::SlotMap<slotmap::DefaultKey, Primitive>,
splitter: BspSplitter<slotmap::DefaultKey>,
max_order: u32,
+ scale_factor: f32,
}
impl Scene {
- pub fn new() -> Scene {
+ pub fn new(scale_factor: f32) -> Scene {
Scene {
opaque_primitives: PrimitiveBatch::default(),
transparent_primitives: slotmap::SlotMap::new(),
splitter: BspSplitter::new(),
max_order: 0,
+ scale_factor,
}
}
pub fn insert(&mut self, primitive: impl Into<Primitive>) {
- let primitive = primitive.into();
+ let mut primitive = primitive.into();
+ primitive.scale(self.scale_factor);
self.max_order = cmp::max(self.max_order, primitive.order());
match primitive {
Primitive::Quad(quad) => self.opaque_primitives.quads.push(quad),
- Primitive::Glyph(glyph) => self.opaque_primitives.glyphs.push(glyph),
- Primitive::Underline(underline) => self.opaque_primitives.underlines.push(underline),
}
}
@@ -47,16 +48,12 @@ impl Scene {
#[derive(Clone, Debug)]
pub enum Primitive {
Quad(Quad),
- Glyph(RenderedGlyph),
- Underline(Underline),
}
impl Primitive {
pub fn order(&self) -> u32 {
match self {
Primitive::Quad(quad) => quad.order,
- Primitive::Glyph(glyph) => glyph.order,
- Primitive::Underline(underline) => underline.order,
}
}
@@ -65,8 +62,14 @@ impl Primitive {
Primitive::Quad(quad) => {
quad.background.is_transparent() && quad.border_color.is_transparent()
}
- Primitive::Glyph(glyph) => glyph.color.is_transparent(),
- Primitive::Underline(underline) => underline.color.is_transparent(),
+ }
+ }
+
+ pub fn scale(&mut self, factor: f32) {
+ match self {
+ Primitive::Quad(quad) => {
+ quad.scale(factor);
+ }
}
}
}
@@ -74,8 +77,6 @@ impl Primitive {
#[derive(Default)]
pub struct PrimitiveBatch {
pub quads: Vec<Quad>,
- pub glyphs: Vec<RenderedGlyph>,
- pub underlines: Vec<Underline>,
}
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
@@ -107,53 +108,19 @@ impl Quad {
}
}
-impl From<Quad> for Primitive {
- fn from(quad: Quad) -> Self {
- Primitive::Quad(quad)
- }
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct RenderedGlyph {
- pub order: u32,
- pub font_id: FontId,
- pub font_size: f32,
- pub id: GlyphId,
- pub origin: Point<Pixels>,
- pub color: Hsla,
-}
-
-impl From<RenderedGlyph> for Primitive {
- fn from(glyph: RenderedGlyph) -> Self {
- Primitive::Glyph(glyph)
+impl Quad {
+ pub fn scale(&mut self, factor: f32) {
+ self.bounds.origin *= factor;
+ self.bounds.size *= factor;
+ self.clip_bounds.origin *= factor;
+ self.clip_corner_radii *= factor;
+ self.corner_radii *= factor;
+ self.border_widths *= factor;
}
}
-#[derive(Copy, Clone, Default, Debug, Zeroable, Pod)]
-#[repr(C)]
-pub struct Underline {
- pub order: u32,
- pub origin: Point<Pixels>,
- pub width: Pixels,
- pub thickness: Pixels,
- pub color: Hsla,
- pub style: LineStyle,
-}
-
-#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)]
-#[repr(C)]
-pub enum LineStyle {
- #[default]
- Solid = 0,
- Squiggly = 1,
-}
-
-unsafe impl Zeroable for LineStyle {}
-unsafe impl Pod for LineStyle {}
-
-impl From<Underline> for Primitive {
- fn from(underline: Underline) -> Self {
- Primitive::Underline(underline)
+impl From<Quad> for Primitive {
+ fn from(quad: Quad) -> Self {
+ Primitive::Quad(quad)
}
}