Checkpoint
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+24
-57
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user