refactor renderer responsable + docs + schema
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
//! # Frame Module
|
||||
//!
|
||||
//! Defines `Frame`, a per-frame RAII wrapper around the surface texture and its TextureView.
|
||||
//! A Frame exists only for the duration of a single rendering pass — it is acquired at the start
|
||||
//! of each frame loop iteration via Context::begin_frame() or Frame::try_new(), used by Renderer
|
||||
//! to write draw commands into the TextureView, then dropped after Renderer::present() submits it.
|
||||
//!
|
||||
//! ## Interaction with Other Modules
|
||||
//! - **context**: provides the Surface from which Frame acquires the current texture.
|
||||
//! - **renderer**: passes Frame's TextureView to render() as the color attachment target.
|
||||
//! - **error**: does not use errors directly; Frame::new() panics on acquisition failure while
|
||||
//! Frame::try_new() returns Option<Self> for graceful recovery.
|
||||
|
||||
pub struct Frame {
|
||||
/// The GPU surface texture representing the current display buffer to be presented.
|
||||
pub surface_texture: wgpu::SurfaceTexture,
|
||||
/// A read-only view into surface_texture, used as the RenderPass color attachment during rendering.
|
||||
pub view: wgpu::TextureView,
|
||||
}
|
||||
|
||||
impl Frame {
|
||||
/// Acquires the next surface texture and creates a TextureView over it.
|
||||
/// Called by the orchestrator (main.rs) at the start of each frame loop iteration.
|
||||
/// Panics if the surface cannot be acquired (e.g., lost, occluded). For non-panicking
|
||||
/// alternatives, use try_new(). Internal steps: 1) get_current_texture() → 2) match Success/Suboptimal → 3) create_view.
|
||||
pub fn new(surface: &wgpu::Surface) -> Self {
|
||||
// In wgpu 30, get_current_texture() returns CurrentSurfaceTexture enum directly (not Result).
|
||||
// All variants are matched to provide explicit error handling instead of panicking —
|
||||
// see Context::begin_frame() for the detailed variant mapping.
|
||||
match surface.get_current_texture() {
|
||||
// On Success or Suboptimal, we acquire the SurfaceTexture and create its TextureView
|
||||
wgpu::CurrentSurfaceTexture::Success(frame)
|
||||
| wgpu::CurrentSurfaceTexture::Suboptimal(frame) => {
|
||||
let view = frame
|
||||
.texture
|
||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
Self {
|
||||
surface_texture: frame,
|
||||
view,
|
||||
}
|
||||
}
|
||||
// Panicking on failure here is intentional — Frame must exist for rendering to proceed.
|
||||
// Callers should use try_new() if they prefer Option-based error recovery.
|
||||
other => panic!("Failed to acquire texture: {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
/// Presents the rendered frame by submitting the acquired surface texture to the GPU queue.
|
||||
/// The frame must have been obtained via new() or try_new(); calling present() twice on the same
|
||||
/// texture is undefined behavior. Called after Renderer::render().
|
||||
pub fn present(self, queue: &wgpu::Queue) {
|
||||
queue.present(self.surface_texture);
|
||||
}
|
||||
|
||||
/// Attempts to acquire the next surface texture without panicking.
|
||||
/// Returns Some(Frame) on success (Success/Suboptimal) or None on any error variant.
|
||||
/// Called when graceful frame skipping is preferred over crashing.
|
||||
pub fn try_new(surface: &wgpu::Surface) -> Option<Self> {
|
||||
match surface.get_current_texture() {
|
||||
wgpu::CurrentSurfaceTexture::Success(frame)
|
||||
| wgpu::CurrentSurfaceTexture::Suboptimal(frame) => {
|
||||
let view = frame
|
||||
.texture
|
||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
Some(Self {
|
||||
surface_texture: frame,
|
||||
view,
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a reference to the TextureView used as the RenderPass color attachment.
|
||||
/// Called by Renderer::render() to pass the view into begin_render_pass().
|
||||
pub fn view(&self) -> &wgpu::TextureView {
|
||||
&self.view
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user