#![forbid(unsafe_code)]
#![warn(missing_docs)]
pub mod atlas;
pub mod batch;
pub mod clip;
pub mod error;
pub mod gpu;
pub mod quality;
pub mod resource;
pub use atlas::{AtlasHandle, AtlasRect, TextureAtlas};
pub use batch::{BatchKey, BlendMode, DrawBatch, PipelineKind, PreparedFrame};
pub use clip::{ClipRect, ClipStack};
pub use error::{map_gpu_error, GpuErrorKind};
pub use gpu::{GpuContext, SolidPipeline, WgpuBackend};
pub use quality::{RenderQuality, ShadowQuality, TextQuality};
pub use resource::{
ResourceId, ResourceRegistry, ShaderGuard, ShaderHandle, TextureGuard, TextureHandle,
};
pub struct WgpuPrep {
pub atlas: atlas::TextureAtlas,
pub clip: clip::ClipStack,
pub quality: quality::RenderQuality,
}
impl WgpuPrep {
pub fn new(atlas_size: u32, quality: quality::RenderQuality) -> Self {
Self {
atlas: atlas::TextureAtlas::new(atlas_size, atlas_size),
clip: clip::ClipStack::new(),
quality,
}
}
pub fn prepare(&mut self, list: &oxiui_core::paint::DrawList) -> batch::PreparedFrame {
let active_clip = self.clip.current().map(|c| [c.x, c.y, c.w, c.h]);
batch::batch(list, active_clip)
}
}
pub struct WgpuRenderer {
_marker: std::marker::PhantomData<()>,
}
impl WgpuRenderer {
pub fn new() -> Self {
Self {
_marker: std::marker::PhantomData,
}
}
}
impl Default for WgpuRenderer {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use oxiui_core::{geometry::Rect, paint::DrawList, Color};
fn red() -> Color {
Color(255, 0, 0, 255)
}
#[test]
fn prepare_empty_drawlist_is_noop() {
let mut prep = WgpuPrep::new(512, RenderQuality::low());
let list = DrawList::new();
let frame = prep.prepare(&list);
assert_eq!(
frame.batches.len(),
0,
"empty list must produce zero batches"
);
assert_eq!(
frame.culled_count, 0,
"empty list must have zero culled commands"
);
}
#[test]
fn prepare_integrates_atlas_and_clip() {
let mut prep = WgpuPrep::new(512, RenderQuality::balanced());
prep.clip.push(ClipRect::new(0.0, 0.0, 100.0, 100.0));
let mut list = DrawList::new();
list.push_rect(Rect::new(10.0, 10.0, 20.0, 20.0), red());
let frame = prep.prepare(&list);
assert_eq!(frame.batches.len(), 1);
assert_eq!(frame.culled_count, 0);
}
}