Skip to content

Commit 3b50c7c

Browse files
authored
Implement basic rendering flow (#1322)
* Implement basic rendering flow * Fix naming. * Actually fix rename.
1 parent af81b42 commit 3b50c7c

File tree

14 files changed

+987
-113
lines changed

14 files changed

+987
-113
lines changed

Cargo.lock

Lines changed: 127 additions & 68 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ffi/build.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use std::env;
2-
use std::path::PathBuf;
1+
use std::{env, path::PathBuf};
32

43
fn main() {
54
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
@@ -11,13 +10,18 @@ fn main() {
1110
let config_path = PathBuf::from(&crate_dir).join("cbindgen.toml");
1211

1312
cbindgen::Builder::new()
14-
.with_config(cbindgen::Config::from_file(&config_path).expect("Failed to load cbindgen.toml"))
13+
.with_config(
14+
cbindgen::Config::from_file(&config_path).expect("Failed to load cbindgen.toml"),
15+
)
1516
.with_crate(&crate_dir)
1617
.generate()
1718
.expect("Unable to generate bindings")
1819
.write_to_file(&output_file);
1920

2021
println!("cargo:rerun-if-changed=src/lib.rs");
2122
println!("cargo:rerun-if-changed=cbindgen.toml");
22-
println!("cargo:warning=Generated header at: {}", output_file.display());
23+
println!(
24+
"cargo:warning=Generated header at: {}",
25+
output_file.display()
26+
);
2327
}

ffi/src/color.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/// A sRGB (?) color
22
#[repr(C)]
3+
#[derive(Debug, Clone, Copy)]
34
pub struct Color {
45
pub r: f32,
56
pub g: f32,
@@ -11,4 +12,4 @@ impl From<Color> for bevy::color::Color {
1112
fn from(color: Color) -> Self {
1213
bevy::color::Color::srgba(color.r, color.g, color.b, color.a)
1314
}
14-
}
15+
}

ffi/src/error.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
use std::{
2+
cell::RefCell,
3+
ffi::{CString, c_char},
4+
panic,
5+
};
6+
17
use renderer::error::ProcessingError;
2-
use std::cell::RefCell;
3-
use std::ffi::{CString, c_char};
4-
use std::panic;
58

69
thread_local! {
710
static LAST_ERROR: RefCell<Option<CString>> = RefCell::new(None);

ffi/src/lib.rs

Lines changed: 132 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
use crate::color::Color;
21
use bevy::prelude::Entity;
2+
use renderer::render::command::DrawCommand;
3+
4+
use crate::color::Color;
35

46
mod color;
57
mod error;
@@ -72,15 +74,40 @@ pub extern "C" fn processing_background_color(window_id: u64, color: Color) {
7274
error::check(|| renderer::background_color(window_entity, color.into()));
7375
}
7476

75-
/// Step the application forward.
77+
/// Begins the draw for the given window.
7678
///
7779
/// SAFETY:
7880
/// - Init has been called and exit has not been called.
7981
/// - This is called from the same thread as init.
8082
#[unsafe(no_mangle)]
81-
pub extern "C" fn processing_update() {
83+
pub extern "C" fn processing_begin_draw(window_id: u64) {
8284
error::clear_error();
83-
error::check(|| renderer::update());
85+
let window_entity = Entity::from_bits(window_id);
86+
error::check(|| renderer::begin_draw(window_entity));
87+
}
88+
89+
/// Flushes recorded draw commands for the given window.
90+
///
91+
/// SAFETY:
92+
/// - Init has been called and exit has not been called.
93+
/// - This is called from the same thread as init.
94+
#[unsafe(no_mangle)]
95+
pub extern "C" fn processing_flush(window_id: u64) {
96+
error::clear_error();
97+
let window_entity = Entity::from_bits(window_id);
98+
error::check(|| renderer::flush(window_entity));
99+
}
100+
101+
/// Ends the draw for the given window and presents the frame.
102+
///
103+
/// SAFETY:
104+
/// - Init has been called and exit has not been called.
105+
/// - This is called from the same thread as init.
106+
#[unsafe(no_mangle)]
107+
pub extern "C" fn processing_end_draw(window_id: u64) {
108+
error::clear_error();
109+
let window_entity = Entity::from_bits(window_id);
110+
error::check(|| renderer::end_draw(window_entity));
84111
}
85112

86113
/// Shuts down internal resources with given exit code, but does *not* terminate the process.
@@ -93,3 +120,104 @@ pub extern "C" fn processing_exit(exit_code: u8) {
93120
error::clear_error();
94121
error::check(|| renderer::exit(exit_code));
95122
}
123+
124+
/// Set the fill color.
125+
///
126+
/// SAFETY:
127+
/// - Init and create_surface have been called.
128+
/// - window_id is a valid ID returned from create_surface.
129+
/// - This is called from the same thread as init.
130+
#[unsafe(no_mangle)]
131+
pub extern "C" fn processing_set_fill(window_id: u64, r: f32, g: f32, b: f32, a: f32) {
132+
error::clear_error();
133+
let window_entity = Entity::from_bits(window_id);
134+
let color = bevy::color::Color::srgba(r, g, b, a);
135+
error::check(|| renderer::record_command(window_entity, DrawCommand::Fill(color)));
136+
}
137+
138+
/// Set the stroke color.
139+
///
140+
/// SAFETY:
141+
/// - Init and create_surface have been called.
142+
/// - window_id is a valid ID returned from create_surface.
143+
/// - This is called from the same thread as init.
144+
#[unsafe(no_mangle)]
145+
pub extern "C" fn processing_set_stroke_color(window_id: u64, r: f32, g: f32, b: f32, a: f32) {
146+
error::clear_error();
147+
let window_entity = Entity::from_bits(window_id);
148+
let color = bevy::color::Color::srgba(r, g, b, a);
149+
error::check(|| renderer::record_command(window_entity, DrawCommand::StrokeColor(color)));
150+
}
151+
152+
/// Set the stroke weight.
153+
///
154+
/// SAFETY:
155+
/// - Init and create_surface have been called.
156+
/// - window_id is a valid ID returned from create_surface.
157+
/// - This is called from the same thread as init.
158+
#[unsafe(no_mangle)]
159+
pub extern "C" fn processing_set_stroke_weight(window_id: u64, weight: f32) {
160+
error::clear_error();
161+
let window_entity = Entity::from_bits(window_id);
162+
error::check(|| renderer::record_command(window_entity, DrawCommand::StrokeWeight(weight)));
163+
}
164+
165+
/// Disable fill for subsequent shapes.
166+
///
167+
/// SAFETY:
168+
/// - Init and create_surface have been called.
169+
/// - window_id is a valid ID returned from create_surface.
170+
/// - This is called from the same thread as init.
171+
#[unsafe(no_mangle)]
172+
pub extern "C" fn processing_no_fill(window_id: u64) {
173+
error::clear_error();
174+
let window_entity = Entity::from_bits(window_id);
175+
error::check(|| renderer::record_command(window_entity, DrawCommand::NoFill));
176+
}
177+
178+
/// Disable stroke for subsequent shapes.
179+
///
180+
/// SAFETY:
181+
/// - Init and create_surface have been called.
182+
/// - window_id is a valid ID returned from create_surface.
183+
/// - This is called from the same thread as init.
184+
#[unsafe(no_mangle)]
185+
pub extern "C" fn processing_no_stroke(window_id: u64) {
186+
error::clear_error();
187+
let window_entity = Entity::from_bits(window_id);
188+
error::check(|| renderer::record_command(window_entity, DrawCommand::NoStroke));
189+
}
190+
191+
/// Draw a rectangle.
192+
///
193+
/// SAFETY:
194+
/// - Init and create_surface have been called.
195+
/// - window_id is a valid ID returned from create_surface.
196+
/// - This is called from the same thread as init.
197+
#[unsafe(no_mangle)]
198+
pub extern "C" fn processing_rect(
199+
window_id: u64,
200+
x: f32,
201+
y: f32,
202+
w: f32,
203+
h: f32,
204+
tl: f32,
205+
tr: f32,
206+
br: f32,
207+
bl: f32,
208+
) {
209+
error::clear_error();
210+
let window_entity = Entity::from_bits(window_id);
211+
error::check(|| {
212+
renderer::record_command(
213+
window_entity,
214+
DrawCommand::Rect {
215+
x,
216+
y,
217+
w,
218+
h,
219+
radii: [tl, tr, br, bl],
220+
},
221+
)
222+
});
223+
}

renderer/Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ version = "0.1.0"
44
edition = "2024"
55

66
[dependencies]
7-
tracing = "0.1"
8-
tracing-subscriber = "0.3"
97
bevy = { workspace = true }
10-
thiserror = "2"
8+
lyon = "1.0"
119
raw-window-handle = "0.6"
10+
thiserror = "2"
11+
tracing = "0.1"
12+
tracing-subscriber = "0.3"
1213

1314
[target.'cfg(target_os = "macos")'.dependencies]
1415
objc2 = { version = "0.6", default-features = false }

renderer/src/error.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use thiserror::Error;
22

33
pub type Result<T> = std::result::Result<T, ProcessingError>;
44

5-
65
#[derive(Error, Debug)]
76
pub enum ProcessingError {
87
#[error("App was accessed from multiple threads")]
@@ -15,4 +14,4 @@ pub enum ProcessingError {
1514
HandleError(#[from] raw_window_handle::HandleError),
1615
#[error("Invalid window handle provided")]
1716
InvalidWindowHandle,
18-
}
17+
}

0 commit comments

Comments
 (0)