Checkpoint

This commit is contained in:
Antonio Scandurra
2023-09-23 14:20:07 -06:00
parent fb69f3d45f
commit 1a5d6aa498
5 changed files with 83 additions and 139 deletions
+49 -17
View File
@@ -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,
}
+6 -57
View File
@@ -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));
// }
+3 -3
View File
@@ -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);
}
}
+24 -57
View File
@@ -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 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;
}
}
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)
}
}
#[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)
}
}