1#[cfg(feature = "glium")]
13#[cfg_attr(docsrs, doc(cfg(feature = "glium")))]
14pub mod glium;
15
16use std::slice;
17
18use crate::{
19 bitmap::{Bitmap, OwnedBitmap},
20 platform::GPUDRIVER,
21 rect::Rect,
22};
23
24#[derive(Debug)]
25pub struct RenderBuffer {
27 pub texture_id: u32,
29 pub width: u32,
31 pub height: u32,
33 pub has_stencil_buffer: bool,
35 pub has_depth_buffer: bool,
37}
38
39impl From<ul_sys::ULRenderBuffer> for RenderBuffer {
40 fn from(rb: ul_sys::ULRenderBuffer) -> Self {
41 RenderBuffer {
42 texture_id: rb.texture_id,
43 width: rb.width,
44 height: rb.height,
45 has_stencil_buffer: rb.has_stencil_buffer,
46 has_depth_buffer: rb.has_depth_buffer,
47 }
48 }
49}
50
51#[derive(Debug)]
52#[allow(non_camel_case_types)]
53pub enum VertexBufferFormat {
55 Format_2f_4ub_2f = ul_sys::ULVertexBufferFormat_kVertexBufferFormat_2f_4ub_2f as isize,
57 Format_2f_4ub_2f_2f_28f =
59 ul_sys::ULVertexBufferFormat_kVertexBufferFormat_2f_4ub_2f_2f_28f as isize,
60}
61
62impl TryFrom<ul_sys::ULVertexBufferFormat> for VertexBufferFormat {
63 type Error = ();
64
65 fn try_from(vbf: ul_sys::ULVertexBufferFormat) -> Result<Self, Self::Error> {
66 match vbf {
67 ul_sys::ULVertexBufferFormat_kVertexBufferFormat_2f_4ub_2f => {
68 Ok(VertexBufferFormat::Format_2f_4ub_2f)
69 }
70 ul_sys::ULVertexBufferFormat_kVertexBufferFormat_2f_4ub_2f_2f_28f => {
71 Ok(VertexBufferFormat::Format_2f_4ub_2f_2f_28f)
72 }
73 _ => Err(()),
74 }
75 }
76}
77
78pub struct VertexBuffer {
83 pub format: VertexBufferFormat,
85 pub buffer: Vec<u8>,
87}
88
89impl TryFrom<ul_sys::ULVertexBuffer> for VertexBuffer {
90 type Error = ();
91
92 fn try_from(vb: ul_sys::ULVertexBuffer) -> Result<Self, Self::Error> {
93 if vb.data.is_null() {
94 return Err(());
95 }
96 let format = VertexBufferFormat::try_from(vb.format)?;
97 let buffer = unsafe { slice::from_raw_parts(vb.data, vb.size as usize) };
98 Ok(VertexBuffer {
99 format,
100 buffer: buffer.to_vec(),
101 })
102 }
103}
104
105pub struct IndexBuffer {
107 pub buffer: Vec<u32>,
108}
109
110impl From<ul_sys::ULIndexBuffer> for IndexBuffer {
111 fn from(vb: ul_sys::ULIndexBuffer) -> Self {
112 assert!(vb.size % 4 == 0);
113 assert!(!vb.data.is_null());
114 let index_slice = unsafe { slice::from_raw_parts(vb.data as _, vb.size as usize / 4) };
115 IndexBuffer {
116 buffer: index_slice.to_vec(),
117 }
118 }
119}
120
121macro_rules! from_ul_arr {
123 ($arr:expr, $from:ident) => {
124 [
125 $arr[0].$from,
126 $arr[1].$from,
127 $arr[2].$from,
128 $arr[3].$from,
129 $arr[4].$from,
130 $arr[5].$from,
131 $arr[6].$from,
132 $arr[7].$from,
133 ]
134 };
135 (mat $arr:expr, $from:ident) => {
136 [
137 from_ul_arr!(mat $arr[0].$from),
138 from_ul_arr!(mat $arr[1].$from),
139 from_ul_arr!(mat $arr[2].$from),
140 from_ul_arr!(mat $arr[3].$from),
141 from_ul_arr!(mat $arr[4].$from),
142 from_ul_arr!(mat $arr[5].$from),
143 from_ul_arr!(mat $arr[6].$from),
144 from_ul_arr!(mat $arr[7].$from),
145 ]
146 };
147 (mat $arr: expr) => {
148 [
149 [$arr[0], $arr[1], $arr[2], $arr[3]],
150 [$arr[4], $arr[5], $arr[6], $arr[7]],
151 [$arr[8], $arr[9], $arr[10], $arr[11]],
152 [$arr[12], $arr[13], $arr[14], $arr[15]],
153 ]
154 };
155}
156
157#[derive(Debug, Clone)]
158pub enum ShaderType {
165 Fill = ul_sys::ULShaderType_kShaderType_Fill as isize,
167 FillPath = ul_sys::ULShaderType_kShaderType_FillPath as isize,
169}
170
171impl TryFrom<ul_sys::ULShaderType> for ShaderType {
172 type Error = ();
173
174 fn try_from(st: ul_sys::ULShaderType) -> Result<Self, Self::Error> {
175 match st {
176 ul_sys::ULShaderType_kShaderType_Fill => Ok(ShaderType::Fill),
177 ul_sys::ULShaderType_kShaderType_FillPath => Ok(ShaderType::FillPath),
178 _ => Err(()),
179 }
180 }
181}
182
183#[derive(Debug, Clone)]
184pub struct GpuState {
187 pub viewport_width: u32,
189 pub viewport_height: u32,
191 pub transform: [f32; 16],
196 pub enable_texturing: bool,
198 pub enable_blend: bool,
203 pub shader_type: ShaderType,
205 pub render_buffer_id: u32,
207 pub texture_1_id: Option<u32>,
209 pub texture_2_id: Option<u32>,
211 pub texture_3_id: Option<u32>,
213 pub uniform_scalar: [f32; 8],
215 pub uniform_vector: [[f32; 4]; 8],
217 pub clip_size: u8,
219 pub clip: [[[f32; 4]; 4]; 8],
221 pub enable_scissor: bool,
223 pub scissor_rect: Rect<i32>,
225}
226
227impl TryFrom<ul_sys::ULGPUState> for GpuState {
228 type Error = ();
229
230 fn try_from(gs: ul_sys::ULGPUState) -> Result<Self, Self::Error> {
231 Ok(GpuState {
232 viewport_width: gs.viewport_width,
233 viewport_height: gs.viewport_height,
234 transform: gs.transform.data,
235 enable_texturing: gs.enable_texturing,
236 enable_blend: gs.enable_blend,
237 shader_type: ShaderType::try_from(gs.shader_type as u32)?,
238 render_buffer_id: gs.render_buffer_id,
239 texture_1_id: if gs.texture_1_id == 0 {
240 None
241 } else {
242 Some(gs.texture_1_id)
243 },
244 texture_2_id: if gs.texture_2_id == 0 {
245 None
246 } else {
247 Some(gs.texture_2_id)
248 },
249 texture_3_id: if gs.texture_3_id == 0 {
250 None
251 } else {
252 Some(gs.texture_3_id)
253 },
254 uniform_scalar: gs.uniform_scalar,
255 uniform_vector: from_ul_arr!(gs.uniform_vector, value),
256 clip_size: gs.clip_size,
257 clip: from_ul_arr!(mat gs.clip, data),
258 enable_scissor: gs.enable_scissor,
259 scissor_rect: Rect::from(gs.scissor_rect),
260 })
261 }
262}
263
264#[derive(Debug, Clone)]
265pub enum GpuCommand {
273 ClearRenderBuffer {
275 render_buffer_id: u32,
277 },
278 DrawGeometry {
280 gpu_state: Box<GpuState>,
284 geometry_id: u32,
286 indices_offset: u32,
288 indices_count: u32,
290 },
291}
292
293impl TryFrom<ul_sys::ULCommand> for GpuCommand {
294 type Error = ();
295
296 fn try_from(gc: ul_sys::ULCommand) -> Result<Self, Self::Error> {
297 match gc.command_type as u32 {
298 ul_sys::ULCommandType_kCommandType_DrawGeometry => Ok(GpuCommand::DrawGeometry {
299 gpu_state: Box::new(GpuState::try_from(gc.gpu_state)?),
300 geometry_id: gc.geometry_id,
301 indices_count: gc.indices_count,
302 indices_offset: gc.indices_offset,
303 }),
304 ul_sys::ULCommandType_kCommandType_ClearRenderBuffer => {
305 Ok(GpuCommand::ClearRenderBuffer {
306 render_buffer_id: gc.gpu_state.render_buffer_id,
307 })
308 }
309 _ => Err(()),
310 }
311 }
312}
313
314pub trait GpuDriver {
325 fn begin_synchronize(&mut self);
331 fn end_synchronize(&mut self);
336 fn next_texture_id(&mut self) -> u32;
341 fn create_texture(&mut self, texture_id: u32, bitmap: OwnedBitmap);
350 fn update_texture(&mut self, texture_id: u32, bitmap: OwnedBitmap);
352 fn destroy_texture(&mut self, texture_id: u32);
354 fn next_render_buffer_id(&mut self) -> u32;
356 fn create_render_buffer(&mut self, render_buffer_id: u32, render_buffer: RenderBuffer);
358 fn destroy_render_buffer(&mut self, render_buffer_id: u32);
360 fn next_geometry_id(&mut self) -> u32;
362 fn create_geometry(
364 &mut self,
365 geometry_id: u32,
366 vertex_buffer: VertexBuffer,
367 index_buffer: IndexBuffer,
368 );
369 fn update_geometry(
371 &mut self,
372 geometry_id: u32,
373 vertex_buffer: VertexBuffer,
374 index_buffer: IndexBuffer,
375 );
376 fn destroy_geometry(&mut self, geometry_id: u32);
378 fn update_command_list(&mut self, command_list: Vec<GpuCommand>);
380}
381
382platform_set_interface_macro! {
383 #[inline]
384 pub(crate) set_gpu_driver<GpuDriver>(lib, gpu_driver -> GPUDRIVER) -> ulPlatformSetGPUDriver(ULGPUDriver) {
385 begin_synchronize() -> () {}
386 end_synchronize() -> () {}
387 next_texture_id(() -> u32) -> () {}
388 create_texture((texture_id: u32, ul_bitmap: ul_sys::ULBitmap)) -> ((texture_id: u32, bitmap: OwnedBitmap)) {
389 let mut bitmap = Bitmap::from_raw(lib.clone(), ul_bitmap).unwrap();
390 let bitmap = OwnedBitmap::from_bitmap(&mut bitmap).unwrap();
391 }
392 update_texture((texture_id: u32, ul_bitmap: ul_sys::ULBitmap)) -> ((texture_id: u32, bitmap: OwnedBitmap)) {
393 let mut bitmap = Bitmap::from_raw(lib.clone(), ul_bitmap).unwrap();
394 let bitmap = OwnedBitmap::from_bitmap(&mut bitmap).unwrap();
395 }
396 destroy_texture((texture_id: u32)) -> ((texture_id: u32)) {}
397 next_render_buffer_id(() -> u32) -> () {}
398 create_render_buffer((render_buffer_id: u32, ul_render_buffer: ul_sys::ULRenderBuffer))
399 -> ((render_buffer_id: u32, render_buffer: RenderBuffer)) {
400 let render_buffer = RenderBuffer::from(ul_render_buffer);
401 }
402 destroy_render_buffer((render_buffer_id: u32)) -> ((render_buffer_id: u32)) {}
403 next_geometry_id(() -> u32) -> () {}
404 create_geometry((geometry_id: u32, ul_vertex_buffer: ul_sys::ULVertexBuffer,
405 ul_index_buffer: ul_sys::ULIndexBuffer)) -> ((geometry_id: u32, vertex_buffer: VertexBuffer, index_buffer: IndexBuffer)) {
406 let vertex_buffer = VertexBuffer::try_from(ul_vertex_buffer).unwrap();
407 let index_buffer = IndexBuffer::from(ul_index_buffer);
408 }
409 update_geometry((geometry_id: u32, ul_vertex_buffer: ul_sys::ULVertexBuffer,
410 ul_index_buffer: ul_sys::ULIndexBuffer)) -> ((geometry_id: u32, vertex_buffer: VertexBuffer, index_buffer: IndexBuffer)) {
411 let vertex_buffer = VertexBuffer::try_from(ul_vertex_buffer).unwrap();
412 let index_buffer = IndexBuffer::from(ul_index_buffer);
413 }
414 destroy_geometry((geometry_id: u32)) -> ((geometry_id: u32)) {}
415 update_command_list((ul_command_list: ul_sys::ULCommandList)) -> ((commands_list: Vec<GpuCommand>)) {
416 assert!(!ul_command_list.commands.is_null());
417 let commands_slice = slice::from_raw_parts(ul_command_list.commands, ul_command_list.size as usize);
418 let commands_list = commands_slice.iter().map(|gc| GpuCommand::try_from(*gc).unwrap()).collect();
419 }
420 }
421}