Skip to main content

WebGl2Backend

Struct WebGl2Backend 

Source
pub struct WebGl2Backend { /* private fields */ }
Expand description

The complete WebGL 2 backend: a context plus the three shadows that make a frame cheap.

§Performance

Three things are shadowed rather than re-queried. The fixed-function state is shadowed by a GlRenderState copy, so applying a state costs only the calls for fields that actually changed. The current texture unit is shadowed by a u32, so binding a texture to the unit that is already active costs no activeTexture at all. The current program is shadowed by a JsValue compared with Object.is, so rebinding the same program costs no useProgram. None of the three can be answered by asking the driver without a synchronous round trip, which is exactly why they are tracked here instead.

Implementations§

Source§

impl WebGl2Backend

Implements construction and lifecycle for the WebGL 2 backend.

Source

pub fn init(config: &RenderConfig) -> Result<WebGl2Backend, WebGl2InitError>

Builds a backend from a render configuration, resolving the canvas, scaling the backing store by the device pixel ratio, and acquiring the webgl2 context.

The shadow state is seeded with the values a freshly created GL context actually starts in rather than with all-zero placeholders, so the first WebGl2Backend::apply_state emits only the calls that genuinely differ from what the driver already set up.

§Arguments
  • &RenderConfig - The rendering configuration.
§Returns
  • Result<WebGl2Backend, WebGl2InitError> - The backend, or a typed error describing the specific failure.
Source

pub fn is_available() -> bool

Reports whether the browser can create a WebGL 2 context at all.

Creates a throwaway off-DOM canvas and requests a webgl2 context. No shaders are compiled and nothing on the page is touched, so this is cheap enough to call as a capability probe before deciding which backend to construct.

§Returns
  • bool - true when a webgl2 context could be acquired.
Source

pub fn resize(&mut self, width: u32, height: u32)

Resizes the canvas backing store and re-points the shadow’s viewport at the new size.

The viewport is written into the shadow rather than issued immediately, because a resize changes the canvas dimensions and the viewport that was correct for the old ones must be re-asserted against the new ones even if the caller’s own state value did not change. Seeding the shadow makes the next WebGl2Backend::apply_state emit it exactly once.

§Arguments
  • u32 - The new physical pixel width, already multiplied by the device pixel ratio.
  • u32 - The new physical pixel height.
Source

pub fn resize_now(&mut self, width: u32, height: u32)

Resizes the canvas backing store and re-asserts the GL viewport immediately, rather than deferring it to the next WebGl2Backend::apply_state.

WebGl2Backend::resize is the cheaper call and is what a render loop should use, because the viewport it seeds is emitted once by the following state apply. This variant exists for the caller that resizes the DOM canvas itself and needs the GL viewport correct before the next paint, with no intervening apply.

§Arguments
  • u32 - The new physical pixel width, already multiplied by the device pixel ratio.
  • u32 - The new physical pixel height.
Source

pub fn is_context_lost(&self) -> bool

Reports whether the context has been lost, which happens when the browser reclaims the GPU: a tab backgrounded for long enough, a driver reset, a device change.

Worth checking once per frame. Every subsequent GL call against a lost context is a no-op that reports no error, so a renderer that does not check silently draws nothing with a clean console.

§Returns
  • bool - true when the context is lost and must be rebuilt.
Source§

impl WebGl2Backend

Implements the state-diffing apply and the frame-level entry points.

Every method here exists to make the per-frame cost proportional to what actually changed rather than to what was asked for.

Source

pub fn apply_state(&mut self, state: &GlRenderState)

Applies a whole GlRenderState, issuing a GL call only for each field that differs from the currently-bound state.

The diff is against a shadow copy of the last applied state, not against the driver, so no getParameter round trip is needed: the driver is known to agree with the shadow because the shadow is only ever updated after the calls that establish it. This is the single largest saving in the whole backend, since a batch of a thousand draws sharing one state pays for it once instead of for a thousand enable / depthFunc / blendFunc / cullFace / colorMask sequences, each of which the driver re-validates.

§Arguments
  • &GlRenderState - The state to make current.
Source

pub fn invalidate_state(&mut self, width: u32, height: u32)

Resets the shadow to the context’s own initial state, which forces the next apply to re-assert everything.

Needed after anything that can change GL state behind the backend’s back: a context restore, a debug extension, or a driver’s own reset. Without it the shadow would claim a state the driver no longer holds and every diffed call would be skipped.

§Arguments
  • u32 - The viewport width to seed the shadow with.
  • u32 - The viewport height to seed the shadow with.
Source

pub fn set_clear_color(&mut self, color: Color)

Sets the color WebGl2Backend::begin_frame clears to.

§Arguments
  • Color - The clear color, with channels in 0.0..=1.0.
Source

pub fn begin_frame( &mut self, context: &WebGl2RenderingContext, width: u32, height: u32, )

Clears the bound framebuffer and folds a full-size viewport into the shadow.

The clear is issued through clearColor plus clear rather than clearBufferfv because the former is a two-call pair the driver folds into a single tile-clear, while the latter is the WebGL 2 entry point that most drivers route through a slower generic path. The viewport is written into the shadow as well, so a caller that set a smaller viewport for a pass does not have it silently left in place by the next frame.

§Arguments
  • &WebGl2RenderingContext - The context to clear through.
  • u32 - The width of the bound framebuffer, in pixels.
  • u32 - The height of the bound framebuffer, in pixels.
Source

pub fn clear_depth(&self, context: &WebGl2RenderingContext)

Clears only the depth buffer, leaving color untouched.

Split out because a second pass that needs a fresh depth range without disturbing the color underneath is common in deferred and post-process work, and a full clear here would throw away results the pass is about to read.

§Arguments
  • &WebGl2RenderingContext - The context to clear through.
Source

pub fn render_frame( &mut self, context: &WebGl2RenderingContext, program: &GlProgram, color: Color, vertex_count: u32, )

Renders a complete frame: clears to color, binds program, and issues one triangle-list draw.

The one-call frame shape a demo loop needs, built from the same primitives the multi-pass API exposes. Geometry is generated inside the vertex shader from gl_VertexID, so there are no vertex buffers to bind; vertex_count is the number of vertices the shader is expected to emit.

§Arguments
  • &WebGl2RenderingContext - The context to draw through.
  • &GlProgram - The program to draw with.
  • Color - The color to clear to before drawing.
  • u32 - The number of vertices to draw.
Source§

impl WebGl2Backend

Implements every draw entry point, plus binding helpers and readback.

Source

pub fn use_program( &mut self, context: &WebGl2RenderingContext, program: &GlProgram, )

Binds a program, issuing useProgram only when it is not already current.

The identity test is Object.is rather than a pointer compare, because a WebGlProgram is a JS handle whose Rust address is a stack slot a later handle may reuse; comparing addresses would let two different programs compare equal and skip a needed rebind.

§Arguments
  • &WebGl2RenderingContext - The context to bind against.
  • &GlProgram - The program to make current.
Source

pub fn bind_texture_unit( &mut self, context: &WebGl2RenderingContext, unit: u32, texture: &GlTexture, )

Binds a texture to a unit, issuing activeTexture only when the unit is not already current.

§Arguments
  • &WebGl2RenderingContext - The context to bind against.
  • u32 - The texture unit index, as passed to [gl_texture_unit].
  • &GlTexture - The texture to bind to that unit.
Source

pub fn draw_arrays( &self, context: &WebGl2RenderingContext, topology: PrimitiveTopology, args: &DrawArgs, )

Draws args.vertex_count vertices from the bound vertex streams.

§Arguments
  • &WebGl2RenderingContext - The context to draw through.
  • PrimitiveTopology - How the vertices are assembled.
  • &DrawArgs - The counts and offsets to draw.
Source

pub fn draw_elements( &self, context: &WebGl2RenderingContext, topology: PrimitiveTopology, args: &DrawIndexedArgs, index_format: IndexFormat, ) -> bool

Draws args.index_count indices from the bound index buffer.

WebGL 2 has no baseVertex, the way WebGPU’s DrawIndexedArgs does: the element offset reaches the vertex fetch through the attribute pointers recorded in the vertex array object instead. base_vertex is therefore only meaningful as an assertion here, and a non-zero value is reported as false rather than silently ignored, because silently ignoring it would draw the wrong mesh with no diagnostic at all.

§Arguments
  • &WebGl2RenderingContext - The context to draw through.
  • PrimitiveTopology - How the vertices are assembled.
  • &DrawIndexedArgs - The counts and offsets to draw.
  • IndexFormat - The element width of the bound index buffer.
§Returns
  • bool - true when the draw was issued, false when base_vertex is non-zero and therefore cannot be honored.
Source

pub fn draw_element_range( &self, context: &WebGl2RenderingContext, topology: PrimitiveTopology, start: u32, end: u32, index_format: IndexFormat, ) -> bool

Draws a contiguous index range without disturbing the rest of the index buffer.

§Arguments
  • &WebGl2RenderingContext - The context to draw through.
  • PrimitiveTopology - How the vertices are assembled.
  • u32 - The first index to read.
  • u32 - The last index to read, inclusive.
  • IndexFormat - The element width of the bound index buffer.
§Returns
  • bool - true when the range was non-empty and was drawn.
Source

pub fn draw_arrays_instanced( &self, context: &WebGl2RenderingContext, topology: PrimitiveTopology, args: &DrawArgs, )

Draws an instanced vertex range, for geometry generated entirely on the GPU.

§Arguments
  • &WebGl2RenderingContext - The context to draw through.
  • PrimitiveTopology - How the vertices are assembled.
  • &DrawArgs - The counts and offsets to draw.
Source

pub fn draw_elements_instanced( &self, context: &WebGl2RenderingContext, topology: PrimitiveTopology, args: &DrawIndexedArgs, index_format: IndexFormat, ) -> bool

Draws an instanced index range, the form a mesh rendered many times per frame takes.

§Arguments
  • &WebGl2RenderingContext - The context to draw through.
  • PrimitiveTopology - How the vertices are assembled.
  • &DrawIndexedArgs - The counts and offsets to draw.
  • IndexFormat - The element width of the bound index buffer.
§Returns
  • bool - true when the draw was issued, false when base_vertex is non-zero and therefore cannot be honored.
Source

pub fn read_pixels( &mut self, context: &WebGl2RenderingContext, x: i32, y: i32, width: u32, height: u32, ) -> Vec<u8> ⓘ

Reads a rectangle of the bound framebuffer back into Rust memory.

The destination buffer is owned by the backend and reused across calls, so a steady-state readback, a picking query or a screenshot say, allocates nothing after the first time it runs at that size. The result is returned as an owned Vec: a caller that needs the bytes past the next readback keeps its own copy, which is one explicit clone rather than a borrow held across a driver call.

Reading from the default framebuffer is legal but slow on most drivers, because the contents may already have been discarded by the compositor; reading from a bound GlFramebuffer is the supported path.

§Arguments
  • &WebGl2RenderingContext - The context to read through.
  • i32 - The left edge in pixels.
  • i32 - The bottom edge in pixels.
  • u32 - The width in pixels.
  • u32 - The height in pixels.
§Returns
  • Vec<u8> - The tightly packed RGBA bytes, row-major from the bottom edge, or empty when the rectangle has no area.
Source§

impl WebGl2Backend

Source

pub fn get_canvas(&self) -> &HtmlCanvasElement

Source

pub fn get_mut_canvas(&mut self) -> &mut HtmlCanvasElement

Source

pub fn set_canvas(&mut self, val: HtmlCanvasElement) -> &mut Self

Source

pub fn get_context(&self) -> &WebGl2RenderingContext

Source

pub fn get_mut_context(&mut self) -> &mut WebGl2RenderingContext

Source

pub fn set_context(&mut self, val: WebGl2RenderingContext) -> &mut Self

Source

pub fn get_shadow(&self) -> &GlRenderState

Source

pub fn get_mut_shadow(&mut self) -> &mut GlRenderState

Source

pub fn set_shadow(&mut self, val: GlRenderState) -> &mut Self

Source

pub fn get_active_unit(&self) -> u32

Source

pub fn get_mut_active_unit(&mut self) -> &mut u32

Source

pub fn set_active_unit(&mut self, val: u32) -> &mut Self

Source

pub fn get_bound_program(&self) -> &JsValue

Source

pub fn get_mut_bound_program(&mut self) -> &mut JsValue

Source

pub fn set_bound_program(&mut self, val: JsValue) -> &mut Self

Source

pub fn get_clear_color_field(&self) -> Color

Source

pub fn get_mut_clear_color_field(&mut self) -> &mut Color

Source

pub fn set_clear_color_field(&mut self, val: Color) -> &mut Self

Source

pub fn get_readback(&self) -> &Vec<u8> ⓘ

Source

pub fn set_readback(&mut self, val: Vec<u8>) -> &mut Self

Trait Implementations§

Source§

impl Clone for WebGl2Backend

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for WebGl2Backend

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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<S, T> Upcast<T> for S
where T: UpcastFrom<S> + ?Sized, S: ?Sized,

Source§

fn upcast(&self) -> &T
where Self: ErasableGeneric, T: Sized + ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider ref type within the Wasm bindgen generics type system. Read more
Source§

fn upcast_into(self) -> T
where Self: Sized + ErasableGeneric, T: Sized + ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider type within the Wasm bindgen generics type system. Read more