WIP
This commit is contained in:
@@ -138,6 +138,9 @@ pub struct Bounds<T: Clone + Debug> {
|
||||
pub size: Size<T>,
|
||||
}
|
||||
|
||||
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> {
|
||||
pub fn upper_right(&self) -> Point<T> {
|
||||
Point {
|
||||
@@ -174,6 +177,12 @@ pub struct Edges<T: Clone + Debug> {
|
||||
pub left: T,
|
||||
}
|
||||
|
||||
impl<T: Clone + Debug + Copy> Copy for Edges<T> {}
|
||||
|
||||
unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Edges<T> {}
|
||||
|
||||
unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Edges<T> {}
|
||||
|
||||
impl Edges<Length> {
|
||||
pub fn auto() -> Self {
|
||||
Self {
|
||||
@@ -231,6 +240,21 @@ impl Edges<Pixels> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Refineable, Clone, Default, Debug)]
|
||||
#[refineable(debug)]
|
||||
pub struct Corners<T: Clone + Debug> {
|
||||
pub top_left: T,
|
||||
pub top_right: T,
|
||||
pub bottom_right: T,
|
||||
pub bottom_left: T,
|
||||
}
|
||||
|
||||
impl<T: Clone + Debug + Copy> Copy for Corners<T> {}
|
||||
|
||||
unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Corners<T> {}
|
||||
|
||||
unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Corners<T> {}
|
||||
|
||||
#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
|
||||
#[repr(transparent)]
|
||||
pub struct Pixels(pub(crate) f32);
|
||||
|
||||
@@ -8,9 +8,10 @@ pub struct Renderer {
|
||||
queue: wgpu::Queue,
|
||||
surface: wgpu::Surface,
|
||||
surface_config: wgpu::SurfaceConfiguration,
|
||||
pipeline: wgpu::RenderPipeline,
|
||||
quad_pipeline: wgpu::RenderPipeline,
|
||||
vertex_buffer: wgpu::Buffer,
|
||||
vertex_count: u32,
|
||||
uniforms_buffer: wgpu::Buffer,
|
||||
}
|
||||
|
||||
pub(crate) trait RenderTarget: HasRawWindowHandle + HasRawDisplayHandle {
|
||||
@@ -52,12 +53,9 @@ impl Renderer {
|
||||
// quality takes priority over input latency.
|
||||
present_mode: wgpu::PresentMode::Fifo,
|
||||
|
||||
// Use the Premultiplied alpha mode. With premultiplication, the color components
|
||||
// are multiplied by the alpha value before storage or blending, meaning calculations
|
||||
// with colors already factor in the influence of alpha. This typically results
|
||||
// in better performance and avoids a separate multiplication operation during blending.
|
||||
alpha_mode: wgpu::CompositeAlphaMode::PreMultiplied,
|
||||
|
||||
// When blending, assume the RGB have not yet been multiplied by the alpha channel.
|
||||
alpha_mode: wgpu::CompositeAlphaMode::PostMultiplied,
|
||||
PostMultiplied
|
||||
// Specify the color formats for the views the surface can have.
|
||||
// In this case, the format is BGRA (blue, green, red, alpha) with unsigned
|
||||
// normalised integers in the 8-bit range and the color space is sRGB (standard RGB).
|
||||
@@ -78,6 +76,13 @@ impl Renderer {
|
||||
source: wgpu::ShaderSource::Wgsl(include_str!("shader.frag.wgsl").into()),
|
||||
});
|
||||
|
||||
let uniforms_buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: Some("Uniforms Buffer"),
|
||||
size: std::mem::size_of::<QuadUniforms>() as wgpu::BufferAddress,
|
||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
|
||||
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Render Pipeline Layout"),
|
||||
bind_group_layouts: &[],
|
||||
@@ -91,17 +96,17 @@ impl Renderer {
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
|
||||
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
let quad_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Render Pipeline"),
|
||||
layout: Some(&pipeline_layout),
|
||||
vertex: wgpu::VertexState {
|
||||
module: &vs_module,
|
||||
entry_point: "main",
|
||||
entry_point: "quad",
|
||||
buffers: &[],
|
||||
},
|
||||
fragment: Some(wgpu::FragmentState {
|
||||
module: &fs_module,
|
||||
entry_point: "main",
|
||||
entry_point: "quad",
|
||||
targets: &[Some(wgpu::ColorTargetState {
|
||||
format: surface_config.format,
|
||||
blend: Some(wgpu::BlendState::REPLACE),
|
||||
@@ -122,9 +127,10 @@ impl Renderer {
|
||||
queue,
|
||||
surface,
|
||||
surface_config,
|
||||
pipeline,
|
||||
quad_pipeline,
|
||||
vertex_buffer,
|
||||
vertex_count: 0,
|
||||
uniforms_buffer,
|
||||
}
|
||||
}
|
||||
.boxed()
|
||||
@@ -163,8 +169,9 @@ impl Renderer {
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
|
||||
render_pass.set_pipeline(&self.pipeline);
|
||||
render_pass.set_pipeline(&self.quad_pipeline);
|
||||
render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
|
||||
render_pass.set_bind_group(0, &self.uniforms_buffer, &[]);
|
||||
render_pass.draw(0..self.vertex_count, 0..1);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::{FontId, GlyphId};
|
||||
|
||||
use super::{Bounds, Hsla, Pixels, Point};
|
||||
use crate::{Corners, Edges, FontId, GlyphId};
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use plane_split::BspSplitter;
|
||||
|
||||
@@ -69,13 +68,12 @@ pub struct PrimitiveBatch {
|
||||
pub struct Quad {
|
||||
pub order: f32,
|
||||
pub bounds: Bounds<Pixels>,
|
||||
pub clip_bounds: Bounds<Pixels>,
|
||||
pub clip_corner_radii: Corners<Pixels>,
|
||||
pub background: Hsla,
|
||||
pub border_color: Hsla,
|
||||
pub corner_radius: Pixels,
|
||||
pub border_left: Pixels,
|
||||
pub border_right: Pixels,
|
||||
pub border_top: Pixels,
|
||||
pub border_bottom: Pixels,
|
||||
pub corner_radii: Corners<Pixels>,
|
||||
pub border_widths: Edges<Pixels>,
|
||||
}
|
||||
|
||||
impl Quad {
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
[[stage(vertex)]]
|
||||
fn quad_vertex(input: QuadVertexInput) -> QuadVertexOutput {
|
||||
var output: QuadVertexOutput;
|
||||
|
||||
// Apply clip bounds
|
||||
input.bounds_origin = max(input.bounds_origin, input.clip_bounds.xy);
|
||||
input.bounds_size = min(input.bounds_size, input.clip_bounds.zw);
|
||||
|
||||
var ndc: vec2<f32> = (input.bounds_origin / uniforms.window_size) * 2.0 - 1.0;
|
||||
|
||||
output.position = vec4<f32>(ndc, 0.0, 1.0);
|
||||
output.position.y = -output.position.y; // Inverting since NDC's origin is at the center and y is up
|
||||
output.color = input.color;
|
||||
output.bounds = input.bounds_size / uniforms.window_size; // Convert size to NDC
|
||||
output.corner_radii = input.corner_radii / uniforms.window_size; // Convert corner radii to NDC
|
||||
output.clip_bounds = input.clip_bounds / uniforms.window_size; // Convert clip bounds to NDC
|
||||
output.clip_corner_radii = input.corner_radii / uniforms.window_size; // Convert clip corner radii to NDC
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// #[derive(Debug, Clone, Copy)]
|
||||
// #[repr(C)]
|
||||
// pub struct gpui3::scene::Quad {
|
||||
// pub order: f32,
|
||||
// pub bounds: Bounds<Pixels>,
|
||||
// pub clip_bounds: Bounds<Pixels>,
|
||||
// pub clip_corner_radii: Corners<Pixels>,
|
||||
// pub background: Hsla,
|
||||
// pub border_color: Hsla,
|
||||
// pub corner_radii: Corners<Pixels>,
|
||||
// pub border_widths: Edges<Pixels>,
|
||||
// }
|
||||
|
||||
struct QuadVertexInput {
|
||||
[[location(0)]] order: f32;
|
||||
[[location(1)]] bounds: vec4<f32>; // Bounds<Pixels>
|
||||
[[location(2)]] clip_bounds: vec4<f32>; // Bounds<Pixels>
|
||||
[[location(3)]] clip_corner_radii: vec4<f32>; // Corners<Pixels>
|
||||
[[location(4)]] color: vec4<f32>; // Hsla
|
||||
[[location(5)]] border_color: vec4<f32>; // Hsla
|
||||
[[location(6)]] corner_radii: vec4<f32>; // Corners<Pixels>
|
||||
[[location(7)]] border_widths: vec4<f32>; // Edges<Pixels>
|
||||
};
|
||||
|
||||
[[block]]
|
||||
struct Uniforms {
|
||||
viewport: vec2<f32>;
|
||||
};
|
||||
|
||||
[[binding(0), group(0)]] var<uniform> uniforms: Uniforms;
|
||||
|
||||
struct QuadVertexOutput {
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
[[location(0)]] color: vec4<f32>;
|
||||
[[location(1)]] border_color: vec4<f32>;
|
||||
[[location(2)]] bounds: vec4<f32>;
|
||||
[[location(3)]] corner_radii: vec4<f32>; // assuming topLeft, topRight, bottomRight, bottomLeft
|
||||
[[location(4)]] clip_bounds: vec4<f32>;
|
||||
[[location(5)]] clip_corner_radii: vec4<f32>;
|
||||
[[location(6)]] border_widths: vec4<f32>;
|
||||
};
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn quad_fragment(input: QuadVertexOutput) -> [[location(0)]] vec4<f32> {
|
||||
var output_color: vec4<f32>;
|
||||
var sdf = rounded_quad_sdf(input.position, input.bounds, input.corner_radii);
|
||||
var alpha = clamp(1.0 - sdf, 0.0, 1.0);
|
||||
var border_color: vec4<f32> = input.border_color;
|
||||
var mix_factor: f32 = 1.0 - clamp(sdf, 0.0, 1.0); // Mixing factor dependent on sdf distance
|
||||
|
||||
var border_width_factor: vec4<f32> = normalize(input.border_widths); // Normalizing the border width to account for directional widths
|
||||
|
||||
output_color = mix(input.color, border_color, mix_factor * border_width_factor); // Modulate the mix_factor with the border_width_factor to handle different border widths
|
||||
|
||||
output_color.a = alpha;
|
||||
|
||||
return output_color;
|
||||
}
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn rounded_quad_sdf(p: vec2<f32>, b: vec2<f32>, r: vec4<f32>) -> f32 {
|
||||
var rx: vec2<f32>;
|
||||
rx = select(r.xy, r.zw, greaterThan(p.x, 0.0));
|
||||
rx.x = select(rx.x, rx.y, greaterThan(p.y, 0.0));
|
||||
var q: vec2<f32> = abs(p)-b+rx.x;
|
||||
return min(max(q.x,q.y),0.0) + length(max(q, vec2<f32>(0.0, 0.0))) - rx.x;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::{
|
||||
rems, AbsoluteLength, Bounds, DefiniteLength, Edges, EdgesRefinement, FontStyle, FontWeight,
|
||||
Hsla, Length, Pixels, Point, PointRefinement, Rems, Result, RunStyle, SharedString, Size,
|
||||
SizeRefinement, ViewContext, WindowContext,
|
||||
use crate::{
|
||||
rems, AbsoluteLength, Bounds, Corners, CornersRefinement, DefiniteLength, Edges,
|
||||
EdgesRefinement, FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rems,
|
||||
Result, RunStyle, SharedString, Size, SizeRefinement, ViewContext, WindowContext,
|
||||
};
|
||||
use refineable::Refineable;
|
||||
pub use taffy::style::{
|
||||
@@ -86,7 +86,7 @@ pub struct Style {
|
||||
|
||||
/// The radius of the corners of this element
|
||||
#[refineable]
|
||||
pub corner_radii: CornerRadii,
|
||||
pub corner_radii: Corners<AbsoluteLength>,
|
||||
|
||||
/// The color of text within this element. Cascades to children unless overridden.
|
||||
pub text_color: Option<Hsla>,
|
||||
@@ -243,7 +243,7 @@ impl Default for Style {
|
||||
flex_basis: Length::Auto,
|
||||
fill: None,
|
||||
border_color: None,
|
||||
corner_radii: CornerRadii::default(),
|
||||
corner_radii: Corners::default(),
|
||||
text_color: None,
|
||||
font_size: Some(rems(1.)),
|
||||
font_family: None,
|
||||
|
||||
Reference in New Issue
Block a user