Skip to main content

Frame

Struct Frame 

Source
pub struct Frame<'w> { /* private fields */ }
Expand description

Context for a single frame of rendering.

Frame represents a single frame being rendered. It holds the acquired surface texture and collects command buffers from render passes. When dropped, it automatically submits all command buffers and presents the surface.

§Key Design Points

  • Immutable reference: RenderPasses take &Frame, not &mut Frame
  • RefCell for command buffers: Allows multiple passes without mutable borrow
  • Atomic stats: Thread-safe pass/draw counting
  • RAII cleanup: Drop handles submit and present

§Example

let frame = window.begin_frame().expect("Surface available");

// Create first pass
{
    let mut pass = frame.render_pass()
        .clear_color(Color::BLACK)
        .build();
    // Render background
}

// Create second pass (different encoder)
{
    let mut pass = frame.render_pass()
        .load_color()
        .build();
    // Render UI overlay
}

// Auto-submits on drop

Implementations§

Source§

impl<'w> Frame<'w>

Source

pub fn surface_view(&self) -> &TextureView

Get the surface texture view for this frame.

§Panics

Panics if the surface has been consumed. Use try_surface_view() for fallible access.

Source

pub fn try_surface_view(&self) -> Option<&TextureView>

Try to get the surface texture view for this frame.

Source

pub fn depth_view(&self) -> Option<&TextureView>

Get the window’s depth texture view, if the window was created with depth.

This provides access to the window-owned depth buffer for render passes that need depth testing.

Source

pub fn surface_format(&self) -> TextureFormat

Get the surface texture format.

Source

pub fn size(&self) -> (u32, u32)

Get the frame size in physical pixels.

Source

pub fn graphics(&self) -> &GraphicsContext

Get the graphics context.

Source

pub fn device(&self) -> &Device

Get the wgpu device.

Source

pub fn queue(&self) -> &Queue

Get the wgpu queue.

Source

pub fn stats(&self) -> FrameStats

Get frame statistics.

Source

pub fn gpu_profiler(&self) -> Option<&GpuFrameProfiler>

Get the GPU profiler if attached.

Source

pub fn has_gpu_profiler(&self) -> bool

Check if GPU profiling is active.

Source

pub fn create_encoder(&self, label: Option<&str>) -> CommandEncoder

Create a command encoder for custom command recording.

Use this for operations that don’t fit the render pass model, like buffer copies or texture uploads.

Source

pub fn add_command_buffer(&self, buffer: CommandBuffer)

Add a pre-built command buffer to the frame.

Use this when you have custom command recording logic.

Source

pub fn render_pass(&self) -> RenderPassBuilder<'_, 'w>

Start building a render pass.

Returns a builder that can be configured with target, clear operations, and depth settings before building the actual pass.

Examples found in repository?
examples/camera_demo.rs (line 108)
89    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
90        if window_id != self.window_id {
91            return;
92        }
93
94        events.dispatch(|event| {
95            if let astrelis_winit::event::Event::WindowResized(size) = event {
96                self.window.resized(*size);
97                astrelis_winit::event::HandleStatus::consumed()
98            } else {
99                astrelis_winit::event::HandleStatus::ignored()
100            }
101        });
102
103        let Some(frame) = self.window.begin_frame() else {
104            return; // Surface not available
105        };
106        {
107            let _pass = frame
108                .render_pass()
109                .clear_color(Color::from_rgb_u8(20, 30, 40))
110                .label("camera_demo_pass")
111                .build();
112        }
113        // Frame auto-submits on drop
114    }
More examples
Hide additional examples
examples/mesh_primitives.rs (line 110)
91    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
92        if window_id != self.window_id {
93            return;
94        }
95
96        events.dispatch(|event| {
97            if let astrelis_winit::event::Event::WindowResized(size) = event {
98                self.window.resized(*size);
99                astrelis_winit::event::HandleStatus::consumed()
100            } else {
101                astrelis_winit::event::HandleStatus::ignored()
102            }
103        });
104
105        let Some(frame) = self.window.begin_frame() else {
106            return; // Surface not available
107        };
108        {
109            let _pass = frame
110                .render_pass()
111                .clear_color(Color::from_rgb_u8(20, 30, 40))
112                .label("mesh_primitives_pass")
113                .build();
114        }
115        // Frame auto-submits on drop
116    }
examples/render_graph_demo.rs (line 108)
89    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
90        if window_id != self.window_id {
91            return;
92        }
93
94        events.dispatch(|event| {
95            if let astrelis_winit::event::Event::WindowResized(size) = event {
96                self.window.resized(*size);
97                astrelis_winit::event::HandleStatus::consumed()
98            } else {
99                astrelis_winit::event::HandleStatus::ignored()
100            }
101        });
102
103        let Some(frame) = self.window.begin_frame() else {
104            return; // Surface not available
105        };
106        {
107            let _pass = frame
108                .render_pass()
109                .clear_color(Color::from_rgb_u8(20, 30, 40))
110                .label("render_graph_demo_pass")
111                .build();
112        }
113        // Frame auto-submits on drop
114    }
examples/window_manager_demo.rs (line 108)
86    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
87        // Get the color for this window
88        let Some(&color) = self.window_colors.get(&window_id) else {
89            return;
90        };
91
92        // WindowManager automatically handles:
93        // 1. Window lookup (no manual HashMap.get_mut)
94        // 2. Resize events (automatic)
95        // 3. Event dispatching
96        self.window_manager
97            .render_window(window_id, events, |window, _events| {
98                // No need to manually handle resize events!
99                // WindowManager already did that for us
100
101                // Just render!
102                let Some(frame) = window.begin_frame() else {
103                    return; // Surface not available
104                };
105
106                {
107                    let _pass = frame
108                        .render_pass()
109                        .clear_color(color)
110                        .label("window_manager_pass")
111                        .build();
112                    // Additional rendering would go here
113                }
114                // Frame auto-submits on drop
115            });
116    }
examples/material_system.rs (line 131)
105    fn render(&mut self, _ctx: &mut AppCtx, window_id: WindowId, events: &mut EventBatch) {
106        if window_id != self.window_id {
107            return;
108        }
109
110        // Handle resize
111        events.dispatch(|event| {
112            if let astrelis_winit::event::Event::WindowResized(size) = event {
113                self.window.resized(*size);
114                astrelis_winit::event::HandleStatus::consumed()
115            } else {
116                astrelis_winit::event::HandleStatus::ignored()
117            }
118        });
119
120        // In a real application, materials would be bound during rendering:
121        // material.bind(&mut render_pass);
122        // draw_mesh(&mesh);
123
124        // Begin frame
125        let Some(frame) = self.window.begin_frame() else {
126            return; // Surface not available
127        };
128
129        {
130            let _pass = frame
131                .render_pass()
132                .clear_color(Color::from_rgb_u8(20, 30, 40))
133                .label("material_system_pass")
134                .build();
135            // Materials would be applied here in actual rendering
136            // This is a conceptual demonstration
137        }
138        // Frame auto-submits on drop
139    }
examples/sprite_sheet.rs (line 456)
431    fn render(
432        &mut self,
433        _ctx: &mut astrelis_winit::app::AppCtx,
434        window_id: WindowId,
435        events: &mut astrelis_winit::event::EventBatch,
436    ) {
437        let Some(window) = self.windows.get_mut(&window_id) else {
438            return;
439        };
440
441        // Handle resize
442        events.dispatch(|event| {
443            if let astrelis_winit::event::Event::WindowResized(size) = event {
444                window.resized(*size);
445                astrelis_winit::event::HandleStatus::consumed()
446            } else {
447                astrelis_winit::event::HandleStatus::ignored()
448            }
449        });
450
451        let Some(frame) = window.begin_frame() else {
452            return; // Surface not available
453        };
454        {
455            let mut pass = frame
456                .render_pass()
457                .clear_color(Color::rgb(0.1, 0.1, 0.15))
458                .label("sprite_sheet_pass")
459                .build();
460            pass.set_pipeline(&self.pipeline);
461            pass.set_bind_group(0, &self.bind_group, &[]);
462            pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
463            pass.draw(0..6, 0..1);
464        }
465        // Frame auto-submits on drop
466    }
Source

pub fn compute_pass(&self) -> ComputePassBuilder<'_, 'w>

Start building a compute pass.

Source

pub fn submit(self)

Submit all collected command buffers and present the surface.

This is called automatically on drop, but can be called explicitly for more control over timing.

Trait Implementations§

Source§

impl Drop for Frame<'_>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<'w> !Freeze for Frame<'w>

§

impl<'w> !RefUnwindSafe for Frame<'w>

§

impl<'w> Send for Frame<'w>

§

impl<'w> !Sync for Frame<'w>

§

impl<'w> Unpin for Frame<'w>

§

impl<'w> UnsafeUnpin for Frame<'w>

§

impl<'w> !UnwindSafe for Frame<'w>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> WasmNotSend for T
where T: Send,