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.rsforTextureFormatFeaturesdefaults 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-existingWebGl2RenderingContextto wgpu, which is necessary for some embedding scenarios where the host page already created the context. - Web fence behavior —
GlFenceBehaviorinwgpu-typeslets the user opt into different GL fence strategies. Important for browsers that don't exposeGL_ARB_syncpredictably. - 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 inAdapter::downlevel_capabilities. - A new command — add a variant to
gles::Commandincommand.rs, then handle it ingles::Queue::execute_command. - A new windowing path — sit alongside
egl.rs/wgl.rs/web.rs, then wire it intogles::Instance::new. - Driver bug workaround — these tend to live in
gles/queue.rs(where actual GL calls happen) or ingles/adapter.rs(capability gating).
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.