use concinnity_core::components::{GamepadAction, GraphicsConfig, PostProcessConfig};
use concinnity_core::ecs::asset_id::AssetId;
use concinnity_core::ecs::{Entity, PipelineContext, StepResult, System};
use concinnity_core::gfx::render_types::{DrawIndex, SkinnedIndex};
use concinnity_core::input::keymap;
use concinnity_core::render::backend::RenderBackend;
use concinnity_core::render::history_reset::HistoryResetTracker;
use concinnity_core::render::post::rt_reflections::RtReflectionSettings;
use concinnity_core::render::post::ssao::settings::SsaoSettings;
use concinnity_core::render::post::ssgi::settings::SsgiSettings;
use concinnity_core::render::post::ssr::settings::SsrSettings;
use concinnity_core::render::{backend, overlay_maps, scene_flow, snapshot, text};
use concinnity_core::settings::SettingKey;
use concinnity_core::transform::propagation;
use concinnity_host::store::paths::StateTree;
const IDENTITY4: [[f32; 4]; 4] = crate::gfx::draw_list::IDENTITY4;
struct PickCandidate {
asset_id: AssetId,
entity: Entity,
local_min: [f32; 3],
local_max: [f32; 3],
}
pub(crate) struct GraphicsSystem {
state: Option<StateTree>,
clear_color: [f32; 4],
max_frames: Option<u64>,
failed: bool,
render_secs: f32,
frame_count: u64,
frame_policy: frame_policy::FramePolicy,
menu_mode: bool,
backend: Option<Box<dyn RenderBackend>>,
scene_flow: Option<scene_flow::SceneFlow>,
scene_visibility: scene::SceneVisibilityScratch,
loaded_fonts: text::FontSet,
sprite_texture_slots: overlay_maps::TextureSlots,
debug_hud_chips: Vec<AssetId>,
stat_hud_chips: Vec<AssetId>,
pick_candidates: Vec<PickCandidate>,
texture_streamer: Option<crate::gfx::streaming::texture::TextureStreamer>,
mesh_streamer: Option<crate::gfx::streaming::mesh::MeshStreamer>,
mesh_stream_draw_indices: Vec<DrawIndex>,
chunk_stream: Option<crate::gfx::streaming::system::ChunkStreamState>,
shader_warmup: Option<crate::gfx::streaming::shader::ShaderWarmup>,
deferred_shader_scenes: Vec<(u32, AssetId)>,
clip_rects: overlay_maps::ClipRects,
caps: backend::DeviceCapabilities,
transform_cache: propagation::TransformCache,
pushed_sky_angle: Option<f32>,
history_reset: HistoryResetTracker,
model_push: model_push::ModelPushCache<DrawIndex>,
skinned_model_push: model_push::ModelPushCache<SkinnedIndex>,
snapshot: snapshot::RenderSnapshot,
viewport: (f32, f32),
#[cfg(test)]
pub(crate) test_hooks: Option<crate::gfx::mock_backend::TestHooks>,
}
pub(crate) struct RebindViz {
pub(crate) action: keymap::Bindable,
pub(crate) value_id: AssetId,
}
pub(crate) struct PadRebindViz {
pub(crate) action: GamepadAction,
pub(crate) value_id: AssetId,
}
pub(crate) struct SliderViz {
pub(crate) key: SettingKey,
pub(crate) track_x: f32,
pub(crate) track_w: f32,
pub(crate) handle_w: f32,
pub(crate) handle_id: AssetId,
pub(crate) value_id: AssetId,
}
impl std::fmt::Debug for GraphicsSystem {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("GraphicsSystem")
.field("frame_count", &self.frame_count)
.field("failed", &self.failed)
.finish()
}
}
impl GraphicsSystem {
pub(crate) fn new(tree: Option<&StateTree>) -> Self {
let gfx = GraphicsConfig::default();
Self {
state: tree.cloned(),
clear_color: gfx.clear_color,
max_frames: gfx.max_frames,
failed: false,
render_secs: 0.0,
frame_count: 0,
frame_policy: frame_policy::FramePolicy::default(),
menu_mode: false,
backend: None,
scene_flow: None,
scene_visibility: Default::default(),
loaded_fonts: text::FontSet::default(),
sprite_texture_slots: overlay_maps::TextureSlots::new(),
debug_hud_chips: Vec::new(),
stat_hud_chips: Vec::new(),
pick_candidates: Vec::new(),
texture_streamer: None,
mesh_streamer: None,
mesh_stream_draw_indices: Vec::new(),
chunk_stream: None,
shader_warmup: None,
deferred_shader_scenes: Vec::new(),
clip_rects: overlay_maps::ClipRects::new(),
caps: backend::DeviceCapabilities::ALL,
transform_cache: propagation::TransformCache::default(),
pushed_sky_angle: None,
history_reset: HistoryResetTracker::default(),
model_push: model_push::ModelPushCache::default(),
skinned_model_push: model_push::ModelPushCache::default(),
snapshot: snapshot::RenderSnapshot::default(),
viewport: (0.0, 0.0),
#[cfg(test)]
test_hooks: None,
}
}
fn persisted_settings(&self) -> crate::config::Settings {
#[cfg(test)]
if let Some(hooks) = &self.test_hooks {
return hooks.settings.clone();
}
crate::config::Settings::load(self.state.as_ref())
}
pub(crate) fn assets_dir(&self) -> Option<std::path::PathBuf> {
self.state.as_ref().map(StateTree::assets_dir)
}
fn detect_gpu_profile(&self) -> backend::GpuProfile {
#[cfg(test)]
if let Some(hooks) = &self.test_hooks {
return hooks.gpu_profile;
}
crate::device::probe_gpu_profile().unwrap_or(backend::GpuProfile::UNKNOWN)
}
fn seed_first_launch_preset(&self, persisted: &crate::config::Settings) {
let mut s = persisted.clone();
s.graphics.quality_preset = Some(crate::gfx::quality_preset::QualityPreset::Auto);
if let Err(e) = s.save(self.state.as_ref()) {
tracing::warn!("first-launch quality preset save failed: {e}");
}
}
}
impl System for GraphicsSystem {
fn init(&mut self, ctx: &mut PipelineContext) {
self.run_init(ctx);
}
fn step(&mut self, ctx: &mut PipelineContext) -> StepResult {
self.run_step(ctx)
}
}
pub(crate) fn derive_quality_settings(cfg: &PostProcessConfig) -> backend::QualitySettings {
backend::QualitySettings {
taa: cfg.aa_mode.taa_enabled(),
ssao: SsaoSettings::from_config(cfg),
ssr: SsrSettings::from_config(cfg),
rt_reflections: RtReflectionSettings::from_config(cfg),
ssgi: SsgiSettings::from_config(cfg),
reflection_blur_scale: cfg.reflection_blur_divisor(),
auto_exposure: cfg.auto_exposure_settings(),
auto_exposure_bias_ev: cfg.exposure_ev,
}
}
mod backend_handoff;
mod blob_release;
pub(crate) mod character_shape;
mod draw_geometry;
mod frame;
pub(crate) mod frame_policy;
pub mod hot_reload_sources;
mod init;
mod lines;
mod mesh_seed_compaction;
mod mesh_stream_inputs;
mod model_push;
pub mod parked;
mod prop_draws;
pub(crate) mod scene;
mod scene_lights;
pub mod sdf_field_sources;
pub mod shader_sources;
mod skinned_templates;
mod stream_plan;
mod stream_sources;
mod streaming;
pub(crate) mod submit;
#[cfg(test)]
mod tests;
mod texture_payloads;
mod world_fx;