* a new tribool type in libutils (header only)
* Support `Engine::compile` overload to generate view-dependent variants
Implemented an `Engine::compile()` method to infer and generate shader
permutations directly based on feature states from a provided `View`
alongside `tribool` settings (skinning, shadowReceiver).
- Added a new `Material::compile()` overload that directly accepts
a precalculated `FixedCapacityVector<Variant>`, decoupling the
Material compilation process from specific feature flag checks.
FIXES=[468058969]
- Move the renderer options to be applied before others before view
and camera options.
- Add "render" field to the output of the json description of
the settings (this was missing).
- This fixes the Scene->Background Color setting for
Android's gltf_viewer
This commit introduces several features:
- Backend Testing: Support testing across both OpenGL and Vulkan. Test
configurations expand per backend, and the Filament Engine alongside
ModelViewer is recreated dynamically when the backend switches to isolate
resources.
- UI Controls: Added a backend filter toggle and a test progress bar to the
main activity, themed appropriately using Material design.
- Memory Optimizations: Drastically reduced memory usage by displaying
scaled-down thumbnails (128x128) in the main list. Full-resolution images
are lazy-loaded from disk on demand when clicking a thumbnail to view, and
large bitmaps are aggressively recycled.
- Device Info Collection: ValidationResultManager now collects and reports
detailed GPU driver info for each instantiated backend in the output
results.json.
- Engine Teardown: Introduced an explicit destroy() method in ModelViewer to
ensure full resource cleanup during engine recreation.
This commit addresses several issues with EVSM blur precision
and shadow atlas boundary handling by replacing the global layer blur
with a dedicated, per-shadowmap separated Gaussian blur pass.
Key improvements:
- Per-ShadowMap Blurring: Moved the EVSM blurring and mipmap passes
from `PostProcessManager` to `ShadowMapManager`. Blurring is now
applied individually per shadow map using its specific `blurWidth`,
rather than being incorrectly applied across the entire atlas layer.
- Custom EVSM Gaussian Shader: Introduced a new dedicated
post-processing material (`gaussian.fs` and `gaussian.mat`) tailored
specifically for EVSM.
- Safe FP16 Accumulation: The new blur shader pre-scales the color
accumulation using safe FP16 FMA to strictly prevent `+Inf` overflows
during Gaussian pass sampling.
- Atlas Boundary Clamping: The custom blur shader enforces clamping
to an explicit sub-rectangle (`bounds` uniform) preventing texture
bleed across adjacent shadow maps in the atlas.
- Code Organization: Created a new `evsm/` material directory,
extracting `vsmMipmap.mat` and registering the new `gaussian.mat`.
* fp32 texture formats are not necessarily filterable
Mobile devices don't always support filtering of fp32 textures.
This PR adds a query at the driver level.
High precision EVSM is now conditional to this feature being supported.
* use MTLDevice supports32BitFloatFiltering if available
The OpenGLContext class in the OpenGL backend currently conflates two
distinct parts: immutable configuration (extensions, bugs, capabilities)
and a mutable GL state cache. This single-object design is incompatible
with a multi-threaded rendering architecture, where each thread requires
a dedicated GL context and, critically, its own independent state
machine/cache.
This refactoring implements the proposed architecture by:
1. Introducing a new OpenGLState class to exclusively manage the mutable
GL state cache (texture bindings, buffer bindings, etc.) with
explicit per-thread ownership (e.g., mBackendState and mWorkerState).
2. Ensuring OpenGLContext retains only the shared, immutable
configuration.
3. Preserving the existing gl.XXX usage pattern by implementing inline
accessors in OpenGLState that forward read-only queries (e.g.,
gl.ext.XXX, gl.isES2()) to the back-referenced OpenGLContext.
4. Updating common functions shared between backend and worker threads
to explicitly accept an OpenGLState& parameter.
This change enables a multi-threaded approach by guaranteeing each
thread operates on its own dedicated GL state cache, while reusing the
shared, immutable context configuration.
BUGS=[487347473]
- Fix constant wrap-around: Define `BIT_COUNT`, `BITS_PER_WORD`, and
`WORD_COUNT` (fixed typo from `WORLD_COUNT`) as `size_t` rather than
`T` to prevent silent overflows on large bitsets using small integer
types.
- Fix NEON `all()` truncation: Remove the generic `T` cast to correctly
evaluate bounds across the full 64-bit vector lanes.
- Fix non-NEON `count()` overflow: Use a `size_t` accumulator rather
than `T` to prevent overflow when counting >255 bits on `uint8_t`
parameters.
- Fix NEON strict alignment UB: Enforce unconditional `alignas(16)` on
`storage` when `BIT_COUNT` satisfies 128-bit vector multiples, adding
a compile-time `static_assert` to ensure ABI expectations match NEON
load intrinsics.
- Remove dead masking code inside `firstSetBit()`.
Missing the castShadows=true caused the shadows to be missing
on mobile (using the remote settings page).
Update README.md (this will trigger an update to the remote
page's filament.js)
* Optimize Shader LineDictionary with Variable-Length 3-Streams
This commit completely reorganizes the string dictionary compression
pipeline used by compiled Material Text Chunks and improves matinfo
dictionary output.
1. Multi-Base Variable-Length Scaling:
We replaced the static 16-bit indices overhead with a
bounded payload. Now, indices scale dynamically:
- 0 to 239 evaluate in 1 byte.
- 240 to 3584 leverage 0xF0-0xFD escapes evaluating in 2 bytes.
- 3584+ are locked behind a 0xFF marker to 3 bytes.
This natively eradicated the massive monolithic lengths and zero-padding
issues previously dominating shader packages.
2. Variable-Length 3-Stream Decoding:
To solve the Zstandard/Zlib entropy fragmentation that conventionally
plagues interleaved variable byte lengths (which previously inflated
our `filament.aar` boundary constraint by +2KB), we segregated the encoded
payloads.
By grouping high-entropy string boundaries into a `Base Stream`
and isolating offset digits inside an `Extension Stream`,
predictive LZ77 ZIP sliding-windows perfectly map
over both arrays independently without disruption.
3. Optimize Numeric Stream using LEB128
Prior to this change, numerical suffixes split from shader
variables (e.g., `param_1024` -> `param_` + `1024`) were fed back
into the localized String Dictionary. Because high-frequency numbers were
assigned disjointed localized IDs per shader variant, LZ77
failed to cross-reference their repetitive structures across
shipped `.aar` archives, fracturing compression sequences.
This patch implements a unified 3-Stream topology. It
extracts numerical primitives (< 32768) away from the baseline
String Dictionary, writing them into an isolated, contiguous
LEB128 array.
By using a dedicated `[254]` Escape Token within the primary stream, numerical
variables maintain exact 1-byte (`< 128`) or 2-byte (`>= 128`)
geometric layouts across all permutations.
The resulting deterministic alignment guarantees that Zlib sliding windows
can deduplicate highly repetitive variables across the
entire application binary block.
4. We use the ShaderStage information to create distinct index ranges, which
further help use 1-byte indices.
Verification Metrics:
`filament-android.aar`: -7,938 B
`gltfio-android.aar`: -290,939 B
`libfilament.a`: -18,464 B
* Optimize shader dictionary by decoding '_' for numeric literals
Most numbers extracted from the shader text are preceded by an
underscore (e.g., from `_`, `hp_copy_`), which previously caused
standalone `_` strings to heavily pollute the LineDictionary.
This change removes the standalone `_` from the dictionary index:
- `MaterialChunk` rehydrates the `_` prefix when decoding these numeric
literals.
This frees up dictionary indices, yielding massive byte savings across
uncompressed binaries (e.g., -28.4 KB for volume_masked.filamat).
* Optimize ShaderMinifier to strip explicit spacing
Spirv-cross outputs GLSL with explicit spacing around generic
operators (e.g., ` = `, `, `, ` ) * `). This padding consumes a
significant amount of uncompressed bytes across large ubershaders.
By applying targeted string replacements at the end of the `ShaderMinifier`
pass, we strip this extraneous padding down to its raw tokens
(e.g., `a=b`, `a,b`, `a*b`).
This optimization preserves isolating spaces where valuable, ensuring
line-dictionary tokens (such as raw `=` or `,`) remain deduplicated
instead of fusing into unpredictable variables.
Impact:
This saves roughly ~9.1 KB in `libfilament.a` and ~3.2 KB in
`volume_masked.filamat` uncompressed, with proportional gains across
the downstream LZ4 compressed archives.
* Fix out-of-bounds string read by verifying null-terminator existence
during extraction.
* Fix heap buffer overflow by validating dictionary string lengths
against target shader buffers before copying.
* Fix out-of-bounds array reads by validating chunk-provided lookup
indices against parsed dictionary sizes.
* Fix integer wrapping exploits by replacing pointer addition with
offset subtraction during chunk size verifications.
Add unit tests for these vulerabilities.