pub struct RenderContext { /* private fields */ }Expand description
Owns the wgpu::Instance and the single logical device this crate’s
consumers render with.
A single RenderContext is shared across every surface a shell creates
(frust is single-window); the device is created lazily on the first surface
and reused across surface loss/recreation (rotation, backgrounding) since a
logical device is display-independent. RenderContext::new performs no
adapter enumeration at all, so a host may build one early (before it has a
window, or on a thread that will never render) and pay for the device only
at the first surface — or at an explicit
ensure_device_headless pre-init.
Implementations§
Source§impl RenderContext
impl RenderContext
Sourcepub fn new() -> RenderContext
pub fn new() -> RenderContext
Creates a context with a fresh wgpu Instance and no device yet
(the device is created lazily on first surface creation).
The instance flags come from the build configuration
(InstanceFlags::from_build_config, which turns DEBUG/VALIDATION on
in debug builds) plus the standard WGPU_* environment overrides. When
actually running on an Android emulator they are then run through
effective_instance_flags, which strips DEBUG/VALIDATION: the
DEBUG flag makes wgpu enable VK_EXT_debug_utils and set object-name
labels via vkSetDebugUtilsObjectNameEXT, and the emulator’s gfxstream
Vulkan HAL (vulkan.ranchu.so) segfaults inside that entry point during
adapter enumeration (observed crash: #00 vulkan.ranchu.so vk_common_SetDebugUtilsObjectNameEXT) — the same class of debug-utils
fragility a MoltenVK Vulkan backend is also known to have. Debug object
labels are only a developer convenience, so dropping them on the
emulator is a safe way to keep GPU bring-up alive there while leaving
physical devices’ validation safety net — and desktop behavior —
untouched.
Sourcepub fn with_options(options: ContextOptions) -> RenderContext
pub fn with_options(options: ContextOptions) -> RenderContext
Self::new with an explicit ContextOptions — a headless harness
that must label its device or pin one backend regardless of the ambient
environment. Every shell takes new()’s defaults instead.
Sourcepub fn surface_factory(&self) -> SurfaceFactory
pub fn surface_factory(&self) -> SurfaceFactory
A cloneable SurfaceFactory sharing this context’s wgpu Instance,
for creating a DetachedSurface on
the windowing/main thread when the context itself lives on the render
thread (the render-thread split). The surface a clone produces stays
compatible with the device this context creates, since both share one
Arc-backed instance.
Sourcepub async fn device(&mut self) -> Result<&DeviceHandle, Error>
pub async fn device(&mut self) -> Result<&DeviceHandle, Error>
The logical device, creating it on first call and returning the same one afterwards.
Adapter selection goes through
wgpu::util::initialize_adapter_from_env_or_default, so
WGPU_ADAPTER_NAME/WGPU_POWER_PREF pick the adapter on a host with
more than one — the only way to pin a specific GPU on a multi-adapter
machine.
§Errors
When no adapter is available at all, or when the device request the adapter’s own limits were computed for is nonetheless refused. Both are terminal for GPU rendering; neither is retryable by calling again.
Sourcepub fn caps(&self) -> Option<&TierCaps>
pub fn caps(&self) -> Option<&TierCaps>
What the live device’s adapter reported, or None while the device is
still uncreated — capabilities are an adapter’s answer, and no adapter
has been selected before the first device creation.
Sourcepub fn pipeline_cache_supported(&self) -> bool
pub fn pipeline_cache_supported(&self) -> bool
Whether the live device was created with wgpu::Features::PIPELINE_CACHE.
wgpu only implements the persisted pipeline cache on Vulkan — every
Vulkan adapter advertises it (Android, Linux, Windows-on-Vulkan);
Metal and DX12 adapters never do, so it is absent there and
create_pipeline_cache returns None —
the renderer then behaves exactly as it did before this path existed.
Panics if no surface (and thus no device) has been created yet.
Sourcepub fn adapter_cache_key(&self) -> String
pub fn adapter_cache_key(&self) -> String
The adapter fingerprint a persisted pipeline-cache blob is tagged with
(see crate::pipeline_cache). Panics if no device has been created yet.
Sourcepub async fn ensure_device_headless(&mut self) -> Result<(), Error>
pub async fn ensure_device_headless(&mut self) -> Result<(), Error>
Create the logical device before any surface exists, so the wgpu
instance/adapter/device bring-up can run on a
background thread kicked at native-library load (JNI_OnLoad) and be
joined by nativeInit instead of running serially after surfaceCreated.
Idempotent: a no-op when a device already exists.
§Android singular-adapter assumption
Requesting the adapter with compatible_surface: None picks wgpu’s
default adapter rather than one filtered to a specific surface. On Android
the Vulkan backend exposes a single physical device, so the adapter chosen
here is the same one a later surface-filtered request would pick, and
ensure_device’s is_surface_supported reuse check
accepts it — the surface created at nativeInit reuses this device with no
rebuild. On a hypothetical multi-adapter device where the pre-init adapter
did not support the eventual surface, ensure_device simply rebuilds the
device against that surface (still correct, just without the overlap win).
This is the sole production caller that passes None below; desktop/iOS
create their device through the surface path and never invoke it.