Checkpoint

This commit is contained in:
Antonio Scandurra 2023-09-24 16:52:33 -06:00
parent a7803570dc
commit 55f4aa3b34
4 changed files with 28 additions and 55 deletions

View file

@ -5,7 +5,7 @@ use cocoa::{
foundation::NSUInteger, foundation::NSUInteger,
quartzcore::AutoresizingMask, quartzcore::AutoresizingMask,
}; };
use metal::{CommandQueue, DepthStencilDescriptor, MTLPixelFormat, MTLResourceOptions, NSRange}; use metal::{CommandQueue, MTLPixelFormat, MTLResourceOptions, NSRange};
use objc::{self, msg_send, sel, sel_impl}; use objc::{self, msg_send, sel, sel_impl};
use std::{ffi::c_void, mem, ptr}; use std::{ffi::c_void, mem, ptr};
@ -17,7 +17,6 @@ pub struct MetalRenderer {
layer: metal::MetalLayer, layer: metal::MetalLayer,
command_queue: CommandQueue, command_queue: CommandQueue,
quad_pipeline_state: metal::RenderPipelineState, quad_pipeline_state: metal::RenderPipelineState,
depth_state: metal::DepthStencilState,
unit_vertices: metal::Buffer, unit_vertices: metal::Buffer,
instances: metal::Buffer, instances: metal::Buffer,
} }
@ -88,18 +87,12 @@ impl MetalRenderer {
PIXEL_FORMAT, PIXEL_FORMAT,
); );
let depth_stencil_descriptor = DepthStencilDescriptor::new();
depth_stencil_descriptor.set_depth_compare_function(metal::MTLCompareFunction::LessEqual);
depth_stencil_descriptor.set_depth_write_enabled(true);
let depth_state = device.new_depth_stencil_state(&depth_stencil_descriptor);
let command_queue = device.new_command_queue(); let command_queue = device.new_command_queue();
Self { Self {
device, device,
layer, layer,
command_queue, command_queue,
quad_pipeline_state, quad_pipeline_state,
depth_state,
unit_vertices, unit_vertices,
instances, instances,
} }
@ -154,7 +147,6 @@ impl MetalRenderer {
let alpha = if self.layer.is_opaque() { 1. } else { 0. }; let alpha = if self.layer.is_opaque() { 1. } else { 0. };
color_attachment.set_clear_color(metal::MTLClearColor::new(0., 0., 0., alpha)); color_attachment.set_clear_color(metal::MTLClearColor::new(0., 0., 0., alpha));
let command_encoder = command_buffer.new_render_command_encoder(render_pass_descriptor); let command_encoder = command_buffer.new_render_command_encoder(render_pass_descriptor);
command_encoder.set_depth_stencil_state(&self.depth_state);
command_encoder.set_viewport(metal::MTLViewport { command_encoder.set_viewport(metal::MTLViewport {
originX: 0.0, originX: 0.0,
@ -166,13 +158,15 @@ impl MetalRenderer {
}); });
let mut buffer_offset = 0; let mut buffer_offset = 0;
self.draw_quads( for layer in scene.layers() {
&scene.opaque_primitives().quads, self.draw_quads(
&mut buffer_offset, &layer.quads,
viewport_size, &mut buffer_offset,
scene.max_order(), viewport_size,
command_encoder, command_encoder,
); );
}
command_encoder.end_encoding(); command_encoder.end_encoding();
self.instances.did_modify_range(NSRange { self.instances.did_modify_range(NSRange {
@ -190,7 +184,6 @@ impl MetalRenderer {
quads: &[Quad], quads: &[Quad],
offset: &mut usize, offset: &mut usize,
viewport_size: Size<DevicePixels>, viewport_size: Size<DevicePixels>,
max_order: u32,
command_encoder: &metal::RenderCommandEncoderRef, command_encoder: &metal::RenderCommandEncoderRef,
) { ) {
if quads.is_empty() { if quads.is_empty() {
@ -214,10 +207,7 @@ impl MetalRenderer {
Some(&self.instances), Some(&self.instances),
*offset as u64, *offset as u64,
); );
let quad_uniforms = QuadUniforms { let quad_uniforms = QuadUniforms { viewport_size };
viewport_size,
max_order,
};
let quad_uniform_bytes = bytemuck::bytes_of(&quad_uniforms); let quad_uniform_bytes = bytemuck::bytes_of(&quad_uniforms);
command_encoder.set_vertex_bytes( command_encoder.set_vertex_bytes(
@ -300,5 +290,4 @@ enum QuadInputIndex {
#[repr(C)] #[repr(C)]
pub(crate) struct QuadUniforms { pub(crate) struct QuadUniforms {
viewport_size: Size<DevicePixels>, viewport_size: Size<DevicePixels>,
max_order: u32,
} }

View file

@ -4,7 +4,7 @@
using namespace metal; using namespace metal;
float4 hsla_to_rgba(Hsla hsla); float4 hsla_to_rgba(Hsla hsla);
float4 to_device_position(float2 pixel_position, uint order, uint max_order, float2 viewport_size); float4 to_device_position(float2 pixel_position, float2 viewport_size);
struct QuadVertexOutput { struct QuadVertexOutput {
float4 position [[position]]; float4 position [[position]];
@ -24,7 +24,7 @@ vertex QuadVertexOutput quad_vertex(
Quad quad = quads[quad_id]; Quad quad = quads[quad_id];
float2 position_2d = unit_vertex * float2(quad.bounds.size.width, quad.bounds.size.height) + float2(quad.bounds.origin.x, quad.bounds.origin.y); float2 position_2d = unit_vertex * float2(quad.bounds.size.width, quad.bounds.size.height) + float2(quad.bounds.origin.x, quad.bounds.origin.y);
float2 viewport_size = float2((float)uniforms->viewport_size.width, (float)uniforms->viewport_size.height); float2 viewport_size = float2((float)uniforms->viewport_size.width, (float)uniforms->viewport_size.height);
float4 device_position = to_device_position(position_2d, quad.order, uniforms->max_order, viewport_size); float4 device_position = to_device_position(position_2d, viewport_size);
float4 background_color = hsla_to_rgba(quad.background); float4 background_color = hsla_to_rgba(quad.background);
float4 border_color = hsla_to_rgba(quad.border_color); float4 border_color = hsla_to_rgba(quad.border_color);
return QuadVertexOutput { return QuadVertexOutput {
@ -142,7 +142,6 @@ float4 hsla_to_rgba(Hsla hsla) {
return rgba; return rgba;
} }
float4 to_device_position(float2 pixel_position, uint order, uint max_order, float2 viewport_size) { float4 to_device_position(float2 pixel_position, float2 viewport_size) {
float z = 1. - ((float)order / ((float)max_order + 1.)); return float4(pixel_position / viewport_size * float2(2., -2.) + float2(-1., 1.), 0., 1.);
return float4(pixel_position / viewport_size * float2(2., -2.) + float2(-1., 1.), z, 1.);
} }

View file

@ -1,28 +1,25 @@
use std::cmp;
use super::{Bounds, Hsla, Pixels, Point}; use super::{Bounds, Hsla, Pixels, Point};
use crate::{Corners, Edges, FontId, GlyphId}; use crate::{Corners, Edges};
use bytemuck::{Pod, Zeroable}; use bytemuck::{Pod, Zeroable};
use plane_split::BspSplitter; use collections::BTreeMap;
// Exported to metal // Exported to metal
pub type PointF = Point<f32>; pub type PointF = Point<f32>;
pub struct Scene { pub struct Scene {
opaque_primitives: PrimitiveBatch, layers: BTreeMap<u32, SceneLayer>,
transparent_primitives: slotmap::SlotMap<slotmap::DefaultKey, Primitive>,
splitter: BspSplitter<slotmap::DefaultKey>,
max_order: u32,
scale_factor: f32, scale_factor: f32,
} }
#[derive(Default)]
pub struct SceneLayer {
pub quads: Vec<Quad>,
}
impl Scene { impl Scene {
pub fn new(scale_factor: f32) -> Scene { pub fn new(scale_factor: f32) -> Scene {
Scene { Scene {
opaque_primitives: PrimitiveBatch::default(), layers: Default::default(),
transparent_primitives: slotmap::SlotMap::new(),
splitter: BspSplitter::new(),
max_order: 0,
scale_factor, scale_factor,
} }
} }
@ -30,18 +27,14 @@ impl Scene {
pub fn insert(&mut self, primitive: impl Into<Primitive>) { pub fn insert(&mut self, primitive: impl Into<Primitive>) {
let mut primitive = primitive.into(); let mut primitive = primitive.into();
primitive.scale(self.scale_factor); primitive.scale(self.scale_factor);
self.max_order = cmp::max(self.max_order, primitive.order()); let layer = self.layers.entry(primitive.order()).or_default();
match primitive { match primitive {
Primitive::Quad(quad) => self.opaque_primitives.quads.push(quad), Primitive::Quad(quad) => layer.quads.push(quad),
} }
} }
pub fn opaque_primitives(&self) -> &PrimitiveBatch { pub fn layers(&self) -> impl Iterator<Item = &SceneLayer> {
&self.opaque_primitives self.layers.values()
}
pub fn max_order(&self) -> u32 {
self.max_order
} }
} }
@ -74,11 +67,6 @@ impl Primitive {
} }
} }
#[derive(Default)]
pub struct PrimitiveBatch {
pub quads: Vec<Quad>,
}
#[derive(Debug, Clone, Copy, Zeroable, Pod)] #[derive(Debug, Clone, Copy, Zeroable, Pod)]
#[repr(C)] #[repr(C)]
pub struct Quad { pub struct Quad {
@ -106,9 +94,7 @@ impl Quad {
] ]
.into_iter() .into_iter()
} }
}
impl Quad {
pub fn scale(&mut self, factor: f32) { pub fn scale(&mut self, factor: f32) {
self.bounds.origin *= factor; self.bounds.origin *= factor;
self.bounds.size *= factor; self.bounds.size *= factor;

View file

@ -8,7 +8,6 @@ use derive_more::{Deref, DerefMut};
use refineable::Refineable; use refineable::Refineable;
use std::{ use std::{
any::{Any, TypeId}, any::{Any, TypeId},
future::Future,
marker::PhantomData, marker::PhantomData,
sync::Arc, sync::Arc,
}; };