Open-Source Wikis

/

wgpu

/

Crates

/

GLES backend

gfx-rs/wgpu

GLES backend

Active contributors: Connor Fitzgerald, teoxoy, Inner Daemons

The GLES backend (wgpu-hal/src/gles/) is the catch-all OpenGL backend. It handles desktop OpenGL (3.3+), OpenGL ES (3.0+), WebGL2, and uses ANGLE on macOS as a translation layer to Metal. It's labeled "best-effort" / "downlevel" support — modern WebGPU features like compute shaders, storage buffers, and read/write storage textures are gated by the GLES version.

Directory layout

wgpu-hal/src/gles/
├── mod.rs           ~33 KB — Api impl, types
├── adapter.rs       ~57 KB — feature detection, limits
├── command.rs       ~49 KB — CommandEncoder
├── conv.rs          ~20 KB — type conversions
├── device.rs        ~67 KB — resource creation
├── egl.rs           ~54 KB — EGL context creation (Linux/Android, ANGLE)
├── emscripten.rs    Emscripten shim
├── fence.rs         GL fence sync wrapper
├── queue.rs         ~88 KB — Queue: actually executes recorded GL commands
├── shaders/         GLSL shader sources for utility passes
├── web.rs           ~18 KB — WebGL2 via web-sys
└── wgl.rs           ~30 KB — WGL context creation (Windows)

The largest file is queue.rs (~88 KB) because GLES doesn't have command buffers — CommandEncoder records a list of operations, and Queue::submit is what actually dispatches GL calls in order.

Key abstractions

Type File Purpose
gles::Api wgpu-hal/src/gles/mod.rs HAL Api impl.
gles::Instance, Adapter, Device, Queue wgpu-hal/src/gles/{adapter,mod,queue}.rs Lifecycle.
gles::CommandEncoder wgpu-hal/src/gles/command.rs Records Command enum values into a Vec.
gles::Command wgpu-hal/src/gles/command.rs The recorded command list — one variant per HAL operation.
gles::EglContext, WglContext, WebContext wgpu-hal/src/gles/{egl,wgl,web}.rs Per-windowing-system context wrappers.
gles::Fence wgpu-hal/src/gles/fence.rs GLsync-based fence.

How it works

GLES has no concept of a deferred command buffer that can be recorded on one thread and submitted on another. The backend works around this:

graph LR
    Core[wgpu-core] -->|encode commands| CmdEnc[gles::CommandEncoder]
    CmdEnc -->|push Command::* enum| Vec[Vec<Command>]
    Core -->|queue.submit| Queue[gles::Queue]
    Queue -->|drain Vec, dispatch| Glow[glow GL bindings]
    Glow --> GL[OpenGL / GLES / WebGL2 driver]

The "command buffer" is a tagged-enum vector. Queue::submit walks it and calls into glow (the Rust GL bindings used). This makes the encoder side cheap (just push enum variants); all expensive work happens at submit time on the thread that owns the GL context.

Where each variant runs

Target Context creation Notes
Linux / Android (native) gles::egl.rs (EGL) Default GLES path.
Windows gles::wgl.rs (WGL) Used for desktop OpenGL on Windows.
macOS / iOS EGL via ANGLE macOS doesn't ship a usable OpenGL impl; ANGLE translates to Metal.
Web (wasm) gles::web.rs (WebGL2) Uses web-sys's WebGl2RenderingContext.
Emscripten gles::emscripten.rs Limited; mostly for completeness.

The angle feature on the parent wgpu crate switches macOS to ANGLE/EGL.

Shaders

GLES needs GLSL. wgpu-naga-bridge calls naga::back::glsl to produce GLSL ES 3.0+ source. The backend keeps a small library of GLSL shaders in wgpu-hal/src/gles/shaders/ for internal utility passes (mip generation, clears, etc.).

Limitations

  • No compute shaders before GLES 3.1.
  • No read/write storage textures before GLES 3.1 + extensions.
  • Limited subgroup ops; no cooperative matrices.
  • Limited indirect-draw / indirect-dispatch support — many draws fall back to CPU iteration.
  • Texture format support is sparse compared to native APIs; see wgpu-types/src/texture.rs for TextureFormatFeatures defaults under GLES.

Adapter::downlevel_capabilities (defined in wgpu-hal/src/lib.rs and computed in gles/adapter.rs) returns the actually-supported subset on this device.

Notable features and recent work

  • WebGL2 external context — PR #9438 (Add WebGL2 Adapter::new_external() + context accessor) lets a wasm app pass a pre-existing WebGl2RenderingContext to wgpu, which is necessary for some embedding scenarios where the host page already created the context.
  • Web fence behaviorGlFenceBehavior in wgpu-types lets the user opt into different GL fence strategies. Important for browsers that don't expose GL_ARB_sync predictably.
  • DRM Linux support — Some Linux compositors give wgpu DRM file descriptors directly; the EGL path handles that as well.

Integration points

  • Above: wgpu-core.
  • Below: glow, khronos-egl, glutin/glutin-winit (examples only), glutin_wgl_sys (for WGL), web-sys (for WebGL2).
  • Sideways: ANGLE (external runtime).

Entry points for modification

  • Adding a feature — gate it behind a GLES extension or version check in gles/adapter.rs. Note that some features (STORAGE_RESOURCE_BINDING_ARRAY, etc.) are simply unsupported on GLES — surface that in Adapter::downlevel_capabilities.
  • A new command — add a variant to gles::Command in command.rs, then handle it in gles::Queue::execute_command.
  • A new windowing path — sit alongside egl.rs / wgl.rs / web.rs, then wire it into gles::Instance::new.
  • Driver bug workaround — these tend to live in gles/queue.rs (where actual GL calls happen) or in gles/adapter.rs (capability gating).

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

GLES backend – wgpu wiki | Factory