pub struct SoftwareRenderer { /* private fields */ }Expand description
A running software renderer, produced by SoftwareBackend::into_renderer.
Unlike SoftwareBackend (which is just configuration), this type
always has an active rendering context: its pixel buffer is always
available, and the ctx field is never None, so Output methods
never panic for missing initialization.
Call pixels to inspect the rendered output, or use
Output::draw and Output::draw_layers to render into it.
If the tilesets feature is enabled, the sprite tileset is loaded once, at
into_renderer time, into an internal
SpriteCache. That cache has no reload/hot-swap support (see its
docs); to pick up a changed tileset, rebuild the renderer via a fresh SoftwareBackend
configuration rather than mutating this one.
Implementations§
Source§impl SoftwareRenderer
impl SoftwareRenderer
Sourcepub fn pixels(&self) -> &[u32]
pub fn pixels(&self) -> &[u32]
The rendered pixel buffer, row-major, one u32 per physical pixel.
Each pixel is 0x00RRGGBB: eight bits per channel with the top byte unused (not an alpha
channel, and not premultiplied). Index a pixel as y * width + x, where width = cols * glyph_width * scale and the buffer length is width * rows * glyph_height * scale. Both
dimensions come from this renderer’s
CellGeometry, so prefer deriving them from
surface_size over recomputing the
product by hand.
The contents are whatever the last draw call left behind: Output::draw_layers writes
directly into this buffer rather than through an intermediate frame, so calling this
between draw calls (before the frame is complete) yields a partially drawn buffer rather
than an error. A resize reallocates the buffer, so the returned
slice’s contents and length are only valid until the next resize.
This is always available: there is no Option wrapper because
SoftwareRenderer is guaranteed to have an active rendering context.
Sourcepub fn push_event(&mut self, event: Event)
pub fn push_event(&mut self, event: Event)
Pushes an event into the internal buffer, to be drained by
Input::poll_event.
Sourcepub fn init_surface(
&mut self,
window: Arc<dyn WindowHandle>,
) -> Result<(), SurfaceError>
pub fn init_surface( &mut self, window: Arc<dyn WindowHandle>, ) -> Result<(), SurfaceError>
Initializes the window surface from a raw window/display handle.
The concrete surface is platform-specific (softbuffer on native, a
Canvas2D context on wasm32); see the surface module.
§Errors
On native, returns SurfaceError::Context/SurfaceError::Surface if softbuffer
cannot create a graphics context or surface from window (for example, the handle’s
display or window system connection is invalid). On wasm32, returns
SurfaceError::Canvas if winit’s <canvas> element or its 2D rendering context
cannot be located in the DOM. Either way, self is left without a surface, so
present keeps behaving as headless (a no-op) until init_surface
is called again successfully.
Sourcepub fn resize_surface(&mut self, width: u32, height: u32)
pub fn resize_surface(&mut self, width: u32, height: u32)
Resizes the window surface to width x height pixels. No-op if the
surface has not been initialized via init_surface.
Sourcepub fn present(&mut self) -> Result<(), SurfaceError>
pub fn present(&mut self) -> Result<(), SurfaceError>
Presents the pixel buffer to the window surface. No-op in headless mode (no surface initialized).
§Errors
On native, returns SurfaceError::Surface if softbuffer cannot acquire or present
its buffer (for example, the window was destroyed or the platform surface was lost).
On wasm32, returns SurfaceError::Canvas if building the damaged-row ImageData or
the canvas 2D context’s put_image_data call fails. The pixel buffer and damage
tracking are unaffected by a failed present, so the next successful present resends
the current frame rather than a stale one.
Trait Implementations§
Source§impl Cursor for SoftwareRenderer
impl Cursor for SoftwareRenderer
Source§fn set_cursor_visible(&mut self, _visible: bool)
fn set_cursor_visible(&mut self, _visible: bool)
Source§fn set_cursor_position(&mut self, _position: Pos)
fn set_cursor_position(&mut self, _position: Pos)
Source§fn set_cursor_style(&mut self, _style: CursorStyle)
fn set_cursor_style(&mut self, _style: CursorStyle)
Source§impl Input for SoftwareRenderer
impl Input for SoftwareRenderer
Source§impl Output for SoftwareRenderer
impl Output for SoftwareRenderer
Source§fn draw_layers<'a, I>(&mut self, content: I) -> Result<(), Self::Error>
fn draw_layers<'a, I>(&mut self, content: I) -> Result<(), Self::Error>
Composite the raw layer stream into the pixel buffer.
Layers arrive layer-major (0 first), so painting them in order gives the
correct z-order. Layer 0 always fills its cell background; a higher layer’s
occupied (non-empty) tile always fills a background too, and an empty tile
never does: see the private resolve_bg_fill helper for the exact color each of those
cases paints (it is not always the tile’s own background, to mirror
Grid::flatten_into’s background-inheritance rule exactly). The is_empty
guard matters because this receives the full frame (see
needs_full_frame), including empty
higher-layer cells that must not overwrite layer 0.
This matches cell backends (retroglyph#304): an occupied space with a
Color::Default background on a higher layer erases the glyph beneath it
when flattened, and this backend now does too, by repainting that cell’s
background (see the private resolve_bg_fill helper) even though the occupied tile’s own
background is the default one.
A TileFlags::SPAN_COVERED cell (retroglyph#412) paints its background but not its
glyph: the span’s anchor already drew one sprite across the whole footprint, and the
covered cell’s glyph is that sprite’s text fallback, for backends that cannot draw it. The
sprite-transparency rule that decides whether a background is painted at all is resolved
against the anchor (see resolve_cell_bg), so one span never sits on two different
backdrops.
Source§type Error = Infallible
type Error = Infallible
Source§fn flush(&mut self) -> Result<(), Self::Error>
fn flush(&mut self) -> Result<(), Self::Error>
Source§fn needs_full_frame(&self) -> bool
fn needs_full_frame(&self) -> bool
true if the backend needs the entire frame (all cells on
all layers) on every call to draw_layers, rather
than just the changed cells. Read moreSource§fn composites_layers(&self) -> bool
fn composites_layers(&self) -> bool
draw_layers. Read moreSource§impl Presenter for SoftwareRenderer
impl Presenter for SoftwareRenderer
Source§type SurfaceError = SurfaceError
type SurfaceError = SurfaceError
Source§fn init_surface(
&mut self,
window: Arc<dyn WindowHandle>,
) -> Result<(), SurfaceError>
fn init_surface( &mut self, window: Arc<dyn WindowHandle>, ) -> Result<(), SurfaceError>
Source§fn resize_surface(&mut self, width: u32, height: u32)
fn resize_surface(&mut self, width: u32, height: u32)
Source§fn present(&mut self) -> Result<(), SurfaceError>
fn present(&mut self) -> Result<(), SurfaceError>
Source§fn geometry(&self) -> CellGeometry
fn geometry(&self) -> CellGeometry
CellGeometry rather than the raw
(width, height) pair cell_size returns. Read moreSource§fn scale_factor_changed(&mut self, _scale_factor: f64)
fn scale_factor_changed(&mut self, _scale_factor: f64)
Auto Trait Implementations§
impl Freeze for SoftwareRenderer
impl !RefUnwindSafe for SoftwareRenderer
impl Send for SoftwareRenderer
impl !Sync for SoftwareRenderer
impl Unpin for SoftwareRenderer
impl UnsafeUnpin for SoftwareRenderer
impl !UnwindSafe for SoftwareRenderer
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
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.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.