comfy_core/
render_queues.rs1use crate::*;
2
3static SHADER_UNIFORM_TABLE: Lazy<AtomicRefCell<ShaderUniformTable>> =
4 Lazy::new(|| AtomicRefCell::new(ShaderUniformTable::default()));
5
6#[derive(Default)]
7pub struct ShaderUniformTable {
8 instances: Vec<ShaderInstance>,
9}
10
11pub fn clear_shader_uniform_table() {
12 SHADER_UNIFORM_TABLE.borrow_mut().instances.clear();
13}
14
15pub fn get_shader_instance(
16 id: ShaderInstanceId,
17) -> AtomicRef<'static, ShaderInstance> {
18 AtomicRef::map(SHADER_UNIFORM_TABLE.borrow(), |x| {
19 &x.instances[id.0 as usize]
20 })
21}
22
23pub fn set_uniform(name: impl Into<String>, value: Uniform) {
24 let instance_id = CURRENT_SHADER_INSTANCE_ID.load(Ordering::SeqCst);
25
26 if instance_id > 0 {
27 let mut table = SHADER_UNIFORM_TABLE.borrow_mut();
28
29 if let Some(instance) = table.instances.get(instance_id as usize) {
30 let mut new_instance = instance.clone();
31 new_instance.uniforms.insert(name.into(), value);
32
33 table.instances.push(new_instance);
34
35 CURRENT_SHADER_INSTANCE_ID
36 .store(table.instances.len() as u32 - 1, Ordering::SeqCst);
37 } else {
38 panic!(
39 "Current shader instance id is invalid.
40
41 This is likely a bug, \
42 please report an issue on https://github.com/darthdeus/comfy/issues with \
43 some information on what you did."
44);
45 }
46 } else {
47 panic!("Trying to set a uniform with no shader active");
48 }
49}
50
51static CURRENT_SHADER_INSTANCE_ID: AtomicU32 = AtomicU32::new(0);
52
53pub fn use_shader(shader_id: ShaderId) {
56 let mut table = SHADER_UNIFORM_TABLE.borrow_mut();
57
58 table
59 .instances
60 .push(ShaderInstance { id: shader_id, uniforms: Default::default() });
61
62 CURRENT_SHADER_INSTANCE_ID
63 .store(table.instances.len() as u32 - 1, Ordering::SeqCst);
64}
65
66pub fn use_default_shader() {
68 CURRENT_SHADER_INSTANCE_ID.store(0, Ordering::SeqCst);
69}
70
71pub fn get_current_shader() -> ShaderInstanceId {
73 ShaderInstanceId(CURRENT_SHADER_INSTANCE_ID.load(Ordering::SeqCst))
75}
76
77use std::{
78 collections::BTreeMap,
79 sync::atomic::{AtomicU32, AtomicU64, Ordering},
80};
81
82static SHADER_IDS: AtomicU64 = AtomicU64::new(0);
83
84pub fn gen_shader_id() -> ShaderId {
86 let id = SHADER_IDS.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
87
88 info!("Generated ShaderId: {}", id);
89
90 ShaderId(id)
91}
92
93#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
97pub struct ShaderInstanceId(pub u32);
98
99static TEXT_QUEUE: Lazy<AtomicRefCell<Vec<DrawText>>> =
100 Lazy::new(|| AtomicRefCell::new(Vec::new()));
101
102pub fn consume_text_queue() -> Vec<DrawText> {
103 let mut queue = TEXT_QUEUE.borrow_mut();
104 let mut new_data = Vec::new();
105 std::mem::swap(&mut *queue, &mut new_data);
106 new_data
107}
108
109static RENDER_QUEUES: Lazy<AtomicRefCell<RenderQueues>> =
110 Lazy::new(|| AtomicRefCell::new(RenderQueues::default()));
111
112pub type RenderQueue = Vec<Mesh>;
113
114#[derive(Default)]
115struct RenderQueues {
116 data: BTreeMap<MeshGroupKey, RenderQueue>,
117}
118
119#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
120pub struct MeshGroupKey {
121 pub z_index: i32,
122 pub blend_mode: BlendMode,
123 pub texture_id: TextureHandle,
124 pub shader: ShaderInstanceId,
125 pub render_target: RenderTargetId,
126}
127
128pub fn consume_render_queues() -> BTreeMap<MeshGroupKey, RenderQueue> {
129 let mut queues = RENDER_QUEUES.borrow_mut();
130 let mut new_data = BTreeMap::new();
131 std::mem::swap(&mut new_data, &mut queues.data);
132 new_data
133}
134
135pub fn queue_mesh_draw(mesh: Mesh, blend_mode: BlendMode) {
136 let shader = get_current_shader();
137 let render_target = get_current_render_target();
138
139 RENDER_QUEUES
140 .borrow_mut()
141 .data
142 .entry(MeshGroupKey {
143 z_index: mesh.z_index,
144 blend_mode,
145 texture_id: mesh
146 .texture
147 .unwrap_or_else(|| TextureHandle::from_path("1px")),
148 shader,
149 render_target,
150 })
151 .or_default()
152 .push(mesh);
153}
154
155pub fn draw_text_internal(
156 text: TextData,
157 position: Vec2,
158 align: TextAlign,
159 pro_params: Option<ProTextParams>,
160 params: TextParams,
161) {
162 TEXT_QUEUE.borrow_mut().push(DrawText {
163 text,
164 position,
165 color: params.color,
166 font: params.font,
167 align,
168 pro_params,
169 z_index: params.z_index,
170 });
171}