Compare commits

...

1443 Commits

Author SHA1 Message Date
Powei Feng
ebda7353af Merge branch 'rc/1.70.1' into release 2026-03-24 10:00:30 -07:00
Powei Feng
84c9752493 Update MATERIAL_VERSION to 70 2026-03-23 15:22:20 -07:00
Powei Feng
cab8a89346 vk: make fbo eviction time configurable (#9808)
The previous eviction time is too large (40), then causes memory
to bloat over time. We set the default to 3 (as in triple
buffering), but make it a configurable option via VulkanPlatform.

Fixes #9786
2026-03-23 10:12:41 -07:00
Benjamin Doherty
90254338d6 Bump version to 1.70.1 2026-03-10 13:43:25 -07:00
Benjamin Doherty
06b7c1ffad Merge branch 'rc/1.70.0' into release 2026-03-10 13:43:24 -07:00
Benjamin Doherty
e5fe3d495e Release Filament 1.70.0 2026-03-10 13:43:15 -07:00
Benjamin Doherty
6eff9a9b00 Bump MATERIAL_VERSION to 70 2026-03-10 13:41:32 -07:00
Ben Doherty
2f885cb66d Add Sonatype publishing step to release workflow (#9764) 2026-03-10 13:40:06 -07:00
Mathias Agopian
35f501b3d5 Debug Shadow Cascades: remove dependency on frameUniforms (#9782)
The DebugShadowCasacade material was dependent on frameUniforms,
instead we use material parameters. We also pass all the informations
relative to cascades (it's not used yet, but will be in the future).
2026-03-09 17:14:07 -07:00
Powei Feng
5b799928c3 webgpu: fixes for deadlock, over-flushing (#9776) (#9767)
- In finish(), instead of block to wait for read pixels to finish,
   we poll the state of the counter to ensure that all the readbacks
   are complete.  This allows us to complete the readpixel callbacks
   by advancing webgpu's internal callback counter.
 - Remove all the redundant flushes that are no longer needed now
   that buffer upload is put on the command queue.
 - Add a convenience method for getting swapchain dimensions. Will
   be useful.
 - Add webgpu as a valid backend for running backend tests on linux
   (now that it no longer deadlocks).
2026-03-09 13:05:18 -07:00
Powei Feng
f7f586caff webgpu: fixes for deadlock, over-flushing (#9776)
- In finish(), instead of block to wait for read pixels to finish,
   we poll the state of the counter to ensure that all the readbacks
   are complete.  This allows us to complete the readpixel callbacks
   by advancing webgpu's internal callback counter.
 - Remove all the redundant flushes that are no longer needed now
   that buffer upload is put on the command queue.
 - Add a convenience method for getting swapchain dimensions. Will
   be useful.
 - Add webgpu as a valid backend for running backend tests on linux
   (now that it no longer deadlocks).
2026-03-09 18:14:26 +00:00
Mathias Agopian
5428812b93 remove an unnecessary assert in the froxelixer (#9785) 2026-03-09 10:41:43 -07:00
Patrick Ribas
e57f2f5c02 Add workaround for GLES2 mipmap requirements (#9770) 2026-03-06 16:36:03 -08:00
Mathias Agopian
fd9bcaa735 Fix heap buffer overflow in HDRDecoder RLE decoding (Issue #9748) (#9777)
This commit addresses a critical security vulnerability (OOB write) and 
several stability issues in the Radiance HDR parser.

Primary Fix:
* Fixed a heap buffer overflow in the RLE decoding loop (Issue #9748). 
  The decoder previously failed to verify if a run-length chunk exceeded 
  the remaining space in the scanline buffer. Added strict bounds checking 
  (`num_bytes + run_length > width`) before executing `memset` or 
  `mStream.read` to prevent arbitrary memory corruption.

Additional Security & Stability Improvements:
* Prevented an infinite loop (DoS) in header parsing. Replaced the 
  `do { ... } while(true);` loop with proper stream state checking 
  (`while (mStream.getline(...))`) to handle unexpected EOFs gracefully.
* Mitigated integer overflow and Out-Of-Memory (OOM) vulnerabilities by 
  enforcing maximum sane dimensions (`MAX_IMAGE_DIMENSION` and 
  `MAX_IMAGE_PIXELS`). This prevents catastrophic memory allocations 
  triggered by maliciously crafted width/height values.
* Initialized local variables and buffers (`buf`, `gamma`, `exposure`) to 
  prevent undefined behavior and parsing of stack garbage upon stream read 
  failures.

Fixes #9748
2026-03-06 16:35:24 -08:00
Powei Feng
9a14e54fc2 matdbg: prefer msl when running on metal (#9780)
Keeping ShaderLanguage::UNSPECIFIED will return metal library
as the preferred language on metal.  Here we just make it more
explicit that matdbg needs msl.

Fixes #9372
2026-03-06 21:34:21 +00:00
Powei Feng
d78bb294ed gltf-viewer: enable animation by default (#9778)
The toggle for animation was added recently to Settings and default 
to false. This differs from before where animation is always assumed
to be enabled.

For gltf_viewer's interactive mode, we enable animation. (Batch mode
will still have animation off).

Fixes #9775
2026-03-06 17:46:13 +00:00
haroonq
0b8dbe9b0a Small fix to allow PlatformEGL to work on non-Android targets. (#9724)
- Include gl_headers.h since it defines BACKEND_OPENGL_VERSION_GL(ES)
    depending on which headers are available.
- Don't assume glGetString(GL_EXTENSIONS) returns a non-null value as
    null is a possible return value for OpenGL (desktop).
2026-03-05 15:38:49 -08:00
Powei Feng
e595fd4b79 android-utils: ModelViewer camera manipulator can be null (#9766)
We add the ability for the maniuplator to be null. If it is null,
then the camera settings won't be determined by the manipulator.
This is useful for when we want to set the camera parameters
outside of the modelviewer, but still use it to do everything else.
2026-03-05 20:05:55 +00:00
Ben Doherty
c5d36cff7f Prepare Gradle plugin for publishing (#9773) 2026-03-05 10:50:15 -08:00
Powei Feng
f392e8be54 ppm: move stencil check right before driver calls (#9769)
The init block of addPass will be executed immediately, which means
that even for passes that are culled, we will trip on incorrect format
given to the pass.

We move the stencil check to the execute block of addPass so that
it'll only assert when the pass is actually present in the graph.

FIXES=489437881
2026-03-05 18:11:33 +00:00
Eliza
83653fb358 engine: encapsulate material cache handling (#9663)
* engine: encapsulate material cache handling

We will soon allow `MaterialInstance` to override the value of spec constants.
To avoid code duplication, we introduce a new class `MaterialPrograms` which
handles the chunky bits of managing the program cache and values of the spec
constants.

* MaterialPrograms: add explicit initialize method

* MaterialPrograms: backport fixes, address comments

* MaterialPrograms: set all constants at once

* MaterialPrograms: rename to LocalProgramCache
2026-03-05 06:42:05 +00:00
Eliza
8a3c48fef1 utils: add LRU cache to RefCountedMap (#9730)
* utils: add LRU cache to RefCountedMap

This change introduces a new data structure LruCache and uses it in
RefCountedMap to keep a fixed number of cache entries alive after their
reference count has dropped to zero in the main map.

* utils: address LRU cache comments
2026-03-05 06:04:16 +00:00
Powei Feng
7f6b9bb144 vk: reference rendertarget as part of fbo cache (#9771)
The FBO cache uses imageviews as its cache key. To ensure that these
views are valid for the lifetime of a key-value pair in the cache, we
need to also reference the rendertarget in the value part of the pair.
The RT contains attachments, which are wrappers around
which own the image views.

Fixes #9680
2026-03-04 09:59:05 -08:00
rafadevai
687c42583b VK: Only make a single copy of the descriptor with external samplers (#9765)
When more than one external sampler are present the
flow will clone the descriptor set twice and make a copy
of a binding that requires an immutable sampler. The copy
of this binding will cause a crash in some adreno GPUs.

This change will make sure the descriptor set is only cloned one
and after that only update binding operations are done for the
external sampled bindings.
2026-03-03 18:34:40 -08:00
Mathias Agopian
71e8cab08a Fix a race when garbage-collecting components (#9768)
Not all component managers are thread-safe for garbage-collection. In
particular, some need to access the DriverAPI which is never
thread-safe.

We refactor the garbage-collection code into FEngine, so it's not
duplicated in FRenderer. We make it more explicit that 
FRenderableManager::destroyComponent() needs the DriverAPI, and we
don't call its gc() from a job.

Besides the refactoring, the only change in this CL is that 
FRenderableManager::gc() is no longer called from a job.


FIXES=[489134910]
2026-03-03 13:21:06 -08:00
Ben Doherty
afae31a975 Add Sonatype publishing step to release workflow (#9764) 2026-03-03 12:41:55 -08:00
Powei Feng
5ac5dc4c95 ci: fetch PR ref explicitly to extract commit message for forks (#9756) 2026-03-03 17:24:00 +00:00
Filament Bot
e975572972 [automated] Updating /docs due to commit 29e91f0
Full commit hash is 29e91f0d3a

DOCS_ALLOW_DIRECT_EDITS
2026-03-03 16:21:50 +00:00
Sungun Park
13dcae6d5f Merge branch 'rc/1.69.5' into release 2026-03-03 08:15:44 -08:00
Sungun Park
c14b428acc Bump version to 1.70.0 2026-03-03 08:15:44 -08:00
Sungun Park
29e91f0d3a Release Filament 1.69.5 2026-03-03 08:15:31 -08:00
Mathias Agopian
6f0d47f275 EVSM improvements (#9758)
- refactoring/clecanup to make some changes easier
- VSM mipmap generation was mistakenly disable when blur radius was 0
- analytic variance was disabled because the math only worked for VSM. Fixed the math.
- better handling of large blurs when using fp32
- implement EVSM equivalent of receiver plane normal bias
- use correct EVSM clearing color
- mipmapping with point lights works much better (no seams)
- min variance is computed automatically
- custom high precision mipmaping shader for VSM
2026-03-02 16:46:07 -08:00
Powei Feng
cf66813f41 android: sample-render-validation with new UI and cli tool (#9751)
Android App:
- Refactored activity_main.xml to use modern Material 3 components.
- Grouped Export/Help buttons logically and moved ADB instructions
  to dedicated info icons.
- Added an in-app "Load Test" button to explicitly pick test bundles.
- Updated ValidationInputManager.kt to gracefully handle relative
  zip_path intent execution via ADB targeting app external storage.

Tooling & Documentation:
- Added a Python Textual TUI (validation_app.py) to automate device
  discovery, test execution, bundling, renaming, and
  downloading/uploading.
- Added README.md in test/render-validation documenting ADB intent
  parameter capabilities and TUI dashboard setup.
2026-03-02 23:51:07 +00:00
Powei Feng
5f89e8e711 vk: fix crash when resizing (#9762)
The problem is that we might flush when resizing happens. So
we need to ask for the command buffer "after" the resize/acquire
swapchain logic.

Fixes #9718
2026-02-27 18:14:59 +00:00
Anish Goyal
be9e9298e1 Add a default fence value to VulkanCommands (#9759)
This is useful for the case of certain devices, where a filament::Sync
may be created BEFORE any commands are submitted.
2026-02-27 06:03:30 +00:00
dependabot[bot]
9218b90c9c build(deps): bump the pip group across 1 directory with 2 updates (#9749)
Bumps the pip group with 2 updates in the /test/renderdiff/src directory: [flask](https://github.com/pallets/flask) and [werkzeug](https://github.com/pallets/werkzeug).


Updates `flask` from 3.1.2 to 3.1.3
- [Release notes](https://github.com/pallets/flask/releases)
- [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/flask/compare/3.1.2...3.1.3)

Updates `werkzeug` from 3.1.4 to 3.1.6
- [Release notes](https://github.com/pallets/werkzeug/releases)
- [Changelog](https://github.com/pallets/werkzeug/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/werkzeug/compare/3.1.4...3.1.6)

---
updated-dependencies:
- dependency-name: flask
  dependency-version: 3.1.3
  dependency-type: direct:production
  dependency-group: pip
- dependency-name: werkzeug
  dependency-version: 3.1.6
  dependency-type: direct:production
  dependency-group: pip
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Powei Feng <powei@google.com>
2026-02-27 05:37:29 +00:00
Mathias Agopian
070a07679d Simplify the API of MaterialInstanceManager (#9757)
It's no longer necessary to preallocate a "tag" to reuse a material
instance. Instead, we can simply pass a unique tag when getting the
instance from the pool.
2026-02-26 15:11:31 -08:00
Andrew Wilson
10b7bd71f9 Avoid backend test when building without testing (#9727) 2026-02-26 22:49:58 +00:00
Powei Feng
e4ae96a2a1 renderdiff: disable transmission + webgpu due to flake
RDIFF_ACCEPT_NEW_GOLDENS
2026-02-26 11:52:35 -08:00
Siyu
56ac08e353 Provide thread name when attaching to JVM on Android (#9755)
* Provide thread name when attaching to JVM on Android

When calling AttachCurrentThread on Android, pass a JavaVMAttachArgs structure. This allows providing the thread name, which is retrieved using pthread_getname_np, to the JVM.

* Fix Android build error: pthread_getname_np requires API 26+

---------

Co-authored-by: Mathias Agopian <mathias@google.com>
2026-02-26 10:44:24 -08:00
Siyu
52b0b553b4 Marshall the name size when setting thread name with pthread_setname_np (#9753)
* Marshall the name size when setting thread name with pthread_setname_np.

[pthread_setname_np](https://source.corp.google.com/piper///depot/google3/third_party/android/ndk/stable/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/pthread.h;l=330-341) requires the caller to keep the name within 16 bytes.

After this change, Filament threads like `OpenGLTimerQuer`, `CompilerThreadP`, `CompilerThreadP`, `Filament Choreo`, `FrameInfoGpuCom` would be displayed correctly in the trace.

* Use constexpr MAX_PTHREAD_NAME_LEN

---------

Co-authored-by: Powei Feng <powei@google.com>
Co-authored-by: Mathias Agopian <mathias@google.com>
2026-02-26 10:43:53 -08:00
Filament Bot
00f3c7175c [automated] Updating /docs due to commit e4fa86f
Full commit hash is e4fa86fb01

DOCS_ALLOW_DIRECT_EDITS
2026-02-26 18:05:45 +00:00
Powei Feng
e4fa86fb01 renderdiff: bump golden again
Transimssion.webgpu.TransmissionRoughnessTest seems to have small,
non-flaky differences.

RDIFF_ACCEPT_NEW_GOLDENS
2026-02-26 09:48:30 -08:00
Mathias Agopian
7da2a08df6 replace Variant::VSM with MNT and S2D (#9750)
The VSM variant bit was overloaded, it meant two different things
depending on the DEP bit (depth).

For standard variants (DEP = 0), it decides the type of the shadow
sampler used (PCF or 2D).

For depth variants (DEP = 1), it decides what is written during the
shadow pass (nothing, i.e. depth only, or EVSM depth moments).

We now clearly separate the two bits throughout the code.

This change should be purely source-cosmetic, there shouldn't be any
behavior changes.

Co-authored-by: Powei Feng <powei@google.com>
2026-02-25 16:16:07 -08:00
Powei Feng
82246d934d renderdiff: fix update_golden.py
And fix other python bugs

RDIFF_ACCEPT_NEW_GOLDENS
2026-02-25 15:35:02 -08:00
Filament Bot
c60969ef67 [automated] Updating /docs due to commit ce37f21
Full commit hash is ce37f216bc

DOCS_ALLOW_DIRECT_EDITS
2026-02-25 23:01:55 +00:00
Powei Feng
ce37f216bc Update renderdiff README
RDIFF_ACCEPT_NEW_GOLDENS
2026-02-25 14:58:35 -08:00
Mathias Agopian
81c71fbbb9 Improve shadow normal bias calculation (#9734)
The previous code used the max of the texel's width or height footprint
in world space to compute the offset; this could both overestimate or
underestimate the bias causing some peter panning or acne.

The new code replaces a sqrt with a dot, but is otherwise similar.
2026-02-25 12:16:13 -08:00
Mathias Agopian
07a7c6003a better computation of the jacobian of a projection (#9731)
The previous code was a bit clunky and not generic, it made assumptions
about the shape of the projection matrix. 
This just uses the generic, correct calculation.

In addition the previous code used the wrong matrix, it assumed that
Wp wasn't needed, but it was because translations do change the
jacobian value at a given point.

RDIFF_ACCEPT_NEW_GOLDENS
2026-02-25 12:04:55 -08:00
Sungun Park
804a74c205 Remove unused member in OpenGLContext (#9741) 2026-02-25 19:46:34 +00:00
Anish Goyal
dde49a410a Add inferred template to View.cpp (#9746)
In some cases, this missing template causes build issues when locally
building Impress prebuilts.
2026-02-25 09:19:19 -08:00
Filament Bot
770ce7f8ec [automated] Updating /docs due to commit 11714d3
Full commit hash is 11714d3adc

DOCS_ALLOW_DIRECT_EDITS
2026-02-25 03:44:07 +00:00
Powei Feng
847d657ad5 Merge branch 'rc/1.69.4' into release 2026-02-24 19:37:59 -08:00
Powei Feng
48592d7d22 Bump version to 1.69.5 2026-02-24 19:37:59 -08:00
Powei Feng
11714d3adc Release Filament 1.69.4 2026-02-24 19:37:50 -08:00
Filament Bot
6aac9071b3 [automated] Updating /docs due to commit da9173e
Full commit hash is da9173e9dc

DOCS_ALLOW_DIRECT_EDITS
2026-02-25 03:15:24 +00:00
Powei Feng
da9173e9dc ci: automate renderdiff golden image updates (#9740)
- Introduces the `RDIFF_ACCEPT_NEW_GOLDENS` commit message tag.
- Conditionally skip the `test-renderdiff` presubmit comparison
  if this tag is present.
- Extracts renderdiff generation into a reusable
  `.github/actions/renderdiff-generate` composite action.
- Modifies `postsubmit-main.yml` to automatically generate new
  goldens and push them to a temporary
  `accept-goldens-<short-hash>` branch before merging them into
  `main` when the tag is found.
2026-02-25 03:12:50 +00:00
Anish Goyal
cd64d50408 Fixes FBO destroys for inflight command buffers (#9744)
If a framebuffer is destroyed while a command buffer is in flight (e.g.
during a window resize), it's possible for a command buffer to try to
use a framebuffer that no longer exists. This encapsulates framebuffers
and render passes in resource_ptr, to ensure they are never reclaimed
prematurely.
2026-02-25 01:13:51 +00:00
dependabot[bot]
a3145cb96f Bump minimatch (#9747)
Bumps the npm_and_yarn group with 1 update in the /build/common/upload-release-assets directory: [minimatch](https://github.com/isaacs/minimatch).


Updates `minimatch` from 3.1.2 to 3.1.3
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.3)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 3.1.3
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-24 16:52:35 -08:00
Nick Fisher
cdfb92e14a gltfio: Allow compile-time override of GLTFIO_USE_FILESYSTEM (#9733) 2026-02-24 17:47:49 +00:00
Doris Wu
551add7519 call execute() under single threaded mode (#9738) 2026-02-23 14:22:56 -08:00
Doris Wu
55c16e6e7a call execute() under single threaded mode (#9738) 2026-02-23 22:20:03 +00:00
Powei Feng
65e3c3bfb9 backend: disable autoresolve test for gl+vk on CI (#9742)
BUGS=486954356
2026-02-23 21:57:12 +00:00
Ben Doherty
902f869721 Metal: recreate sidecar texture if sample count changes (#9430) 2026-02-23 09:54:21 -08:00
Eliza
b118ded3fa engine: fix VSM (#9737) 2026-02-22 16:12:31 -08:00
Powei Feng
b3d0416a65 gl: update record when detaching stream (#9712)
FIXES=483744050
2026-02-22 16:12:14 -08:00
Eliza
ad1bc6f360 engine: fix VSM (#9737) 2026-02-20 15:08:59 -08:00
Sungun Park
1d5f6cd6a9 Turn off UBO batching (#9736)
BUGS=[486200381]
2026-02-20 12:09:22 -08:00
Sungun Park
73c343635e Turn off UBO batching (#9736)
BUGS=[486200381]
2026-02-20 20:04:05 +00:00
Mathias Agopian
432e672022 Revert "Swap logic of how the EGL display is initialized. (#9634)" (#9729)
This reverts commit c35ae6571f.

BUGS=[481534922, 478925865]
2026-02-20 08:34:51 -08:00
Doris Wu
b56b04c5f8 Fix translucent objects are pickable when skybox is disabled (#9688) 2026-02-20 11:36:58 +08:00
Filament Bot
99816d67c2 [automated] Updating /docs due to commit d6d4f92
Full commit hash is d6d4f92922

DOCS_ALLOW_DIRECT_EDITS
2026-02-19 20:03:46 +00:00
Mathias Agopian
d6d4f92922 fix intensities (#9728)
DOCS_FORCE
2026-02-19 11:59:34 -08:00
Powei Feng
6a59a68622 gl: update record when detaching stream (#9712)
FIXES=483744050
2026-02-19 18:33:04 +00:00
Filament Bot
4580f57987 [automated] Updating /docs due to commit 38f7e57
Full commit hash is 38f7e579f1

DOCS_ALLOW_DIRECT_EDITS
2026-02-19 17:33:34 +00:00
Benjamin Doherty
5e4c24a7f6 Bump version to 1.69.4 2026-02-19 09:30:21 -08:00
Benjamin Doherty
3c27a83315 Merge branch 'rc/1.69.3' into release 2026-02-19 09:30:20 -08:00
Benjamin Doherty
38f7e579f1 Release Filament 1.69.3 2026-02-19 09:30:12 -08:00
Powei Feng
9b1c8a2bf5 backend: add R11G11B10 format as input to reshaper (#9722) 2026-02-19 00:06:23 -08:00
rafadevai
4504471021 Vulkan: Implement stencil state in pipeline cache (#9716)
Store and set the stencil state for a graphics pipeline.
2026-02-18 20:09:07 +00:00
Powei Feng
37c316fa03 backend: reduce size increase of recent datareshaper change (#9723)
The previous datareshaper change used too multiple parameters
in templates in an attempt to reduce conditionals in the hot-loop.
However, this dramatically increased the binary size.

This change keeps the original intention of not having conditional
in the inner loop, but isolate small sections that need to be
templated into separate components.
2026-02-18 18:12:06 +00:00
Serge Metral
14960f7118 Protected content fix vulkan 2 (#9721)
* Adding the begin frame message for later xtrace post processing.

* Add the flags.

* Cleanup

* Cleanup

---------

Co-authored-by: Powei Feng <powei@google.com>
2026-02-18 09:50:17 -08:00
Powei Feng
1deb657442 github: add sizeguard presubmit test (#9719)
- Add a presubmit check after the android build to check the
   built artifact sizes against previous build sizes.
 - If the size built is +20K over the previous, then the test
   fails.
 - This prevents dramatic size increases of our mobile build
2026-02-18 08:41:58 +00:00
Powei Feng
45c0d1b34f backend: enhance data reshaper (#9711)
- add half float as source type
 - gray-scaled output when src-channel=1 and dest-channel=3 or 4
 - Ensure that per-pixel work is as-constexpr-as-possible
2026-02-17 20:14:34 +00:00
chenriji
1ddd10f326 Fix: Morph Target animations (Blend Shapes) fail to render when loading GLB files via ResourceLoader (#9696)
* fixbug:"debug error, reason: The material 'Material_MR' has not been compiled to include the required GLSL or SPIR-V chunks for the vertex shader (variant=5, filtered=5)",Because the member variable mVariantFilter is not initialized, random values will appear on Windows 10 or others platform, which eventually causes some variants to be filtered out by this mVariantFilter.

* fix:Fix morph target loading for accessors without buffer_view

  Morph targets were not working because ResourceLoader skipped all
  accessors without buffer_view. For morph targets, the data can be
  accessed directly via cgltf_accessor_unpack_floats().

  This fix properly unpacks and uploads morph target vertex data to the
  GPU, enabling blendshapes and facial deformation to work correctly.

Steps to Reproduce
1、In Unity (2022.3.11): Create a Prefab with Blend Shapes (Morph Targets) and an Animator to control them (e.g., an animation clip that makes the eyes squint).
2、Export: Use the UnityGLTF tool to export the model as a .glb file (including the Animator and Morph Target tracks).
3、In Filament: Load and play the animation.
4、Result: The skeletal animation (bone-based) may play, but the Morph Target effect (squinting) is missing or static.
2026-02-13 23:07:17 +00:00
Powei Feng
308668a705 android: render-validation sample UI and additions (#9692)
- Update UI
 - Wait for resources to finish loading before testing
 - Refactor validation to input/output
 - Move assets to be generated from the repo
 - Fix AutomationEngine java binding to add missing fields
2026-02-13 21:53:20 +00:00
Powei Feng
1cd48619e3 github: add scripts to store size of android release artifact (#9705)
- Add a script to test/sizeguard to compute sizes of artifacts
   within a compressed file.
- Add a step to postsubmit-main.yml that will run the above
   script on every commit to main.

This will enable us to add a presubmit step to guard against
dramatic size increases in the Android build.
2026-02-13 20:31:23 +00:00
Sungun Park
89c3b3f40b tools: harden zbloat against command injection (#9715)
This fixes #9701 by replacing shell execution (`shell=True` and
`os.system`) with direct subprocess calls using argument lists in
`tools/zbloat/zbloat.py`

Previously, the script used f-strings to pass paths directly into a
shell command, which created an unnecessary risk: if an external archive
contained files with shell metacharacters, it could lead to accidental
or malicious command execution during analysis.

By passing arguments as lists, the subprocess module maps them directly
to the executable, bypassing the system shell and eliminating the
vulnerability.
2026-02-13 12:03:13 -08:00
Doris Wu
487f4d077d Prevent circular buffer overflow during UboManager reallocation (#9714)
When UboManager::reallocate() is triggered, a large number of material instances may be invalidated simultaneously. This leads to a massive spike in descriptor set updates and command generation, which can overflow the circular buffer.

To prevent this, we now flush commands in batches, we trigger a flush whenever the command buffer usage exceeds half of its capacity. (Like what RenderPass::Executor::execute does)

BUGS = [474264976, 479079631]
2026-02-14 00:48:47 +08:00
Doris Wu
e830ec28e4 Prevent circular buffer overflow during UboManager reallocation (#9714)
When UboManager::reallocate() is triggered, a large number of material instances may be invalidated simultaneously. This leads to a massive spike in descriptor set updates and command generation, which can overflow the circular buffer.

To prevent this, we now flush commands in batches, we trigger a flush whenever the command buffer usage exceeds half of its capacity. (Like what RenderPass::Executor::execute does)

BUGS = [474264976, 479079631]
2026-02-14 00:39:14 +08:00
Sungun Park
e00be09af6 Revert "Set multiview as the default for stereoscopic rendering (#9682)" (#9713)
This reverts commit f10a7d9bbc.
2026-02-12 16:47:48 -08:00
Sungun Park
b58ffb87e0 Revert "Set multiview as the default for stereoscopic rendering (#9682)" (#9713)
This reverts commit f10a7d9bbc.
2026-02-12 22:13:18 +00:00
rafadevai
385d8969cf VK: Fix AHB import validation error (#9710)
In some cases the external image to be imported is
flagged as using a sRGB dataspace but when the AHB
is imported its actual format is UNDEFINED and
requires an external sampler.

In these cases, its not valid to set the
VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT flag.

See VUID-VkImageCreateInfo-pNext-02396

FIXES=[483456747]
2026-02-12 10:19:01 -08:00
Ben Doherty
53bc372876 Log Filament command buffer statistics (#9709) 2026-02-12 12:01:22 -05:00
Andrew Wilson
58f6d77e78 Add build testing checks for all the tests (#9684) 2026-02-11 12:53:40 -08:00
Filament Bot
3769d0a9d3 [automated] Updating /docs due to commit 2bc7124
Full commit hash is 2bc71240cf

DOCS_ALLOW_DIRECT_EDITS
2026-02-11 19:19:32 +00:00
Ramon
2bc71240cf Fix incorrect table structure in README (#9707)
The README had linebreaks that broke the badges in the table.
2026-02-11 19:16:56 +00:00
rafadevai
e1fb3f7442 VK: Fix validation errors when creating a sampler (#9708)
When creating a sampler with a chroma conversion
anisotropic must be disabled and the addressModes
must be set to CLAMP_TO_EDGE.

FIXES = [483454760]
2026-02-11 18:56:22 +00:00
Sungun Park
e832805faf Add cube sample for Web using Feature Level 0 (#9699)
Introduce a new cube sample that utilizes the feature level 0 (FL0) on
the web. The `Engine.create` method accepts `config` as an argument,
allowing users to explicitly request a GLES 2.0 context.

In addition, this change helps a future implementation of asynchronous
support for web, allowing the asynchronous mode to be turned on via the
configuration setting.

BUGS=[476134614]
2026-02-11 09:59:25 -08:00
Filament Bot
2ce71d6d98 [automated] Updating /docs due to commit 26c51e0
Full commit hash is 26c51e0d9a

DOCS_ALLOW_DIRECT_EDITS
2026-02-11 00:10:00 +00:00
Romain Guy
26c51e0d9a Update README with new badge links and features (#9704)
- Replace broken Maven badge links with shields. links
- Updated missing rendering features
2026-02-11 00:07:31 +00:00
rafadevai
510ae15867 VK: Fix the descriptor set layout mismatch errors (#9703)
* VK: Fix the descriptor set layout mismatch errors

Depending on how the descriptor sets and external
sampled images are used is possible to get a lot of
errors about the pipeline layout and the descriptor
set layouts dont match with the validation layers.

This causes flicking artifacts and textures not being
displayed.

This is a partial rewrite of the implementation when
using external samplers through a MaterialInstance.

* Addressing review comments
2026-02-10 15:45:34 -08:00
Powei Feng
d6caa9dc0b diffimg: binary tool for comparing images (#9668)
This tool uses existing libraries: image, imageio, imageio-lite,
imagediff to perform difference comparison for on-disk images.

We refactor renderdiff to use this tool instead of using
python dependencies.


Co-authored-by: Ben Doherty <bendoherty@google.com>
2026-02-10 22:42:30 +00:00
Filament Bot
19209a00e6 [automated] Updating /docs due to commit 188113b
Full commit hash is 188113bad6

DOCS_ALLOW_DIRECT_EDITS
2026-02-10 21:34:43 +00:00
Benjamin Doherty
188113bad6 Update Maven release guide 2026-02-10 16:30:08 -05:00
Powei Feng
5916837318 metal: add readTexture implementation (#9678)
- Also added a test to verify the y-flipping mechanism of
   each backend produces the same rendering across backends.
2026-02-10 19:45:30 +00:00
Ben Doherty
27aa517c48 Add new Filament Gradle plugin (#9694) 2026-02-10 14:15:45 -05:00
Filament Bot
4622e88a6b [automated] Updating /docs due to commit 9bdb6ac
Full commit hash is 9bdb6acd63

DOCS_ALLOW_DIRECT_EDITS
2026-02-10 19:12:10 +00:00
Benjamin Doherty
9bdb6acd63 Update CocoaPods documentation on testing locally 2026-02-10 14:09:25 -05:00
Filament Bot
751d213145 [automated] Updating /docs due to commit 0c3ae45
Full commit hash is 0c3ae457a6

DOCS_ALLOW_DIRECT_EDITS
2026-02-10 18:27:57 +00:00
Sungun Park
7ea1f97b57 Bump version to 1.69.3 2026-02-10 10:22:33 -08:00
Sungun Park
f0a8dc5b64 Merge branch 'rc/1.69.2' into release 2026-02-10 10:22:32 -08:00
Sungun Park
0c3ae457a6 Release Filament 1.69.2 2026-02-10 10:22:22 -08:00
Anish Goyal
92d4be6923 Fix framebuffer cache memory leak (#9693)
Once a framebuffer is destroyed, it must be removed from the mapping,
and not just marked unused. Same for render passes.
2026-02-09 23:36:44 +00:00
Powei Feng
ad8c188f58 3p: update robin-map to 1.4.1 (#9698) 2026-02-09 14:01:48 -08:00
Ben Doherty
fd7baedcdc Changes necessary for GCC (#9672) 2026-02-09 13:36:59 -05:00
Ben Doherty
9716b3924b Changes necessary for GCC (#9672) 2026-02-09 13:36:17 -05:00
Anish Goyal
69fe9f6596 Fix a set of unmapped 3 channel formats (#9690)
These three formats would likely break even if used on a device where
they are supported, as we reshape all 3-channel buffers to 4 channel.
The data would be in the wrong format.

We will have to follow-up, as there are other formats that are affected,
but those formats likely have better driver support, as they are better
aligned formats (e.g. 16-bit, 32-bit). These three formats were 96-bit
formats, which we've remapped to 128-bit.
2026-02-09 10:06:12 -08:00
Anish Goyal
ae9b951b08 Fix a set of unmapped 3 channel formats (#9690)
These three formats would likely break even if used on a device where
they are supported, as we reshape all 3-channel buffers to 4 channel.
The data would be in the wrong format.

We will have to follow-up, as there are other formats that are affected,
but those formats likely have better driver support, as they are better
aligned formats (e.g. 16-bit, 32-bit). These three formats were 96-bit
formats, which we've remapped to 128-bit.
2026-02-09 17:52:22 +00:00
Mathias Agopian
78a0d8f4f6 use correct attachments flags for the current swapchain (#9689)
the current swapchain is associated to the default rendertarget, but
the later doesn't know which attachments the swapchain actually has.
it used to hardcode COLOR and DEPTH, but it's possible for the
swapchain to have a STENCIL attachment.

The proper way to do this is to use the swapchain's attachments when
the default rendertarget is used (which means the swapchain is used).

FIXES=[482120868]
2026-02-06 12:16:04 -08:00
Anish Goyal
675d8bc5be Prevent compilation of redundant pipelines (#9681)
If we've already destroyed a program, we shouldn't run prewarm for it,
as that could entail five pipeline compilations.
2026-02-05 23:39:15 +00:00
Patrick Ribas
a90019baa2 Remove nonlinear fog from FL0 (#9658)
* Remove fog and lighting uniforms from FL0

---------

Co-authored-by: Mathias Agopian <mathias@google.com>
2026-02-05 12:51:37 -08:00
Filament Bot
72997ee71e [automated] Updating /docs due to commit 5b63105
Full commit hash is 5b631056b1

DOCS_ALLOW_DIRECT_EDITS
2026-02-05 06:04:40 +00:00
Powei Feng
712f1edc1e Bump version to 1.69.2 2026-02-04 22:01:59 -08:00
Powei Feng
3d4e7258a6 Merge branch 'rc/1.69.1' into release 2026-02-04 22:01:58 -08:00
Powei Feng
5b631056b1 Release Filament 1.69.1 2026-02-04 22:01:50 -08:00
Powei Feng
6cf499326e github: fix windows release version (#9671)
Use "call" to ensure execution continues after
the batch file.
2026-02-04 21:59:46 -08:00
Ben Doherty
caa334730a Metal: fix debug logging, empty texture usage (#9685) 2026-02-04 16:04:31 -08:00
Powei Feng
261f74a1e9 android: add sample for rendering validation (#9679)
- This is an initial implementation, not yet complete
 - Goal of this sample is to run a series of offscreen single
   frame captures, and capmre the result against a set of golden
   images
 - Uses existing scene description in libs/viewer and
   test/renderdiff
 - Uses existing image difference description/implementation in
   libs/imagediff
 - Add imagediff API to filament-utils-android
2026-02-04 21:57:42 +00:00
Sungun Park
f10a7d9bbc Set multiview as the default for stereoscopic rendering (#9682)
Enables the multiview implementation as the default for stereoscopic
rendering. Now all STE variants use the multiview path.

This change removes all CMake configurations, build scripts, and C++
preprocessors previously used for selecting stereoscopic rendering
modes. And, all shaders are now compiled for multiview.

The instanced rendering implementation is going to be removed. Note that
this commit only handles switching the default. The actual removal of
instanced rendering code will be submitted as a separate follow-up
commit.

BUGS=[470198472]
2026-02-04 17:45:15 +00:00
Powei Feng
358d594f34 gl: implement readTexture (#9652)
This implementation is just a refactor of readPixels.
2026-02-04 17:12:12 +00:00
rafadevai
8cdba6d12e VK: add back the removed vmaFlush for staging (#9674)
This line was removed by accident in the staging bypass
fix PR.
2026-02-03 13:51:14 -08:00
Doris Wu
b06b6b5c42 flip ubobatching flag to true (#9631) 2026-02-03 13:32:20 -08:00
Filament Bot
ac41a15191 [automated] Updating /docs due to commit ef42c55
Full commit hash is ef42c55f56

DOCS_ALLOW_DIRECT_EDITS
2026-02-03 21:19:45 +00:00
Mathias Agopian
ef42c55f56 update java and js bindings (#9676)
* implement some missing javascript bindings

DOCS_FORCE

* use exclusively javadoc comments in Options.h

This is because this file is currently used to generate java and
javascript bindings and doxygen can ingest javadoc.

And regenerate javascript and java bindings

* add missing java bindings
2026-02-03 13:16:01 -08:00
Mathias Agopian
bd67c9c67e Implement missing getters in RenderableManager (#9673)
FIXES=[479883232]
2026-02-03 13:15:18 -08:00
Sungun Park
8f19826fe4 Add multiview support to clearDepth.mat (#9670)
View::setChannelDepthClearEnabled utilizes `clearDepth.mat` internally,
which is not compatible with multiview since clearDepth is
post-process.

This update converts clearDepth.mat into a surface shader, allowing it
to hold the STE variant. This change enables the shader to function
correctly in multiview.

BUGS=[470198472]
2026-02-03 18:18:55 +00:00
Powei Feng
afd0e67fb0 webgpu: implement readTexture (#9655) 2026-02-03 17:41:05 +00:00
rafadevai
f1b14d6f65 VK: add back the removed vmaFlush for staging (#9674)
This line was removed by accident in the staging bypass
fix PR.
2026-02-02 15:39:38 -08:00
Powei Feng
09b5172962 github: fix windows release version (#9671)
Use "call" to ensure execution continues after
the batch file.
2026-02-02 18:42:10 +00:00
Eliza Velasquez
41923df669 engine: fix stereo and parallel shader compilation
Another thing that got lost in the sea of merge conflicts that plagued the
program cache feature...
2026-02-02 08:01:54 -08:00
Eliza Velasquez
51b59bd1c1 engine: fix TAA compilation failure 2026-02-02 08:01:44 -08:00
Powei Feng
9909fd1bf4 filamat: remove unnecessary std::decay_t (#9643) 2026-02-02 08:01:02 -08:00
haroonq
c9ed58733f Swap logic of how the EGL display is initialized. (#9634)
1. Iterate over system displays using eglQueryDevicesEXT and try to initialize them.
2. If no display initialized, then try to initialize the DEFAULT display.

FIXES=[478925865]
2026-02-02 08:00:40 -08:00
Serge Metral
e2c70201b5 External sampler bind index bug (#9664)
Patching a fix for the external sampler use case where the same sampler is bound to two different indices. As it stands, the code fails to differentiate between the two layouts.
2026-02-02 08:00:29 -08:00
Filament Bot
39f0ea1706 [automated] Updating /docs due to commit ec4b911
Full commit hash is ec4b9113df

DOCS_ALLOW_DIRECT_EDITS
2026-01-31 00:54:44 +00:00
Mathias Agopian
ec4b9113df more web sky simulation (#9669)
* fix artifacts on mobile

* feat(skybox): Add moon and milky way rendering

This commit enhances the simulated skybox with the following features:

- **Moon Rendering:** A textured moon with normal mapping has been added. The moon's phase is calculated and rendered correctly. Earthshine is also simulated.
- **Milky Way Background:** An equirectangular milky way texture is now rendered in the background. The intensity and saturation of the milky way can be adjusted.
- **Asset Processing Scripts:** Python scripts have been added to download and process the moon and milky way textures. This includes generating a normal map from a displacement map for the moon.
- **GUI Controls:** The GUI has been updated to include controls for the moon (azimuth, height, intensity, radius) and the milky way (intensity, saturation, sidereal time, latitude).
- **Real-time Sync:** The application can now use the user's geolocation to automatically set the position of the sun and moon.
- **Sun/Moon Calculation:** The  library has been added to calculate the position of the sun and moon.

DOCS_FORCE
2026-01-30 16:51:42 -08:00
Powei Feng
2a51b70a74 fgviewer: add websocket server (#9662)
A preliminary commit to add a websocket server to the DebugServer.
This will enable us to transfer large data (like images) across
to the frontend.

This is part of the work to enable viewing intermediate
render buffers in fgviewer.
2026-01-30 22:36:19 +00:00
Powei Feng
4ba2c7d65c ios: fix build (#9667)
Need to include the new imageio-lite library in the gltf_viewer
sample.
2026-01-30 14:14:54 -08:00
Mathias Agopian
3af28968ed enable skip_frame_when_cpu_ahead_of_display (#9636)
skip_frame_when_cpu_ahead_of_display is now enabled by default.

BUGS=[474599530]
2026-01-30 12:59:04 -08:00
Mathias Agopian
2f36ab71c9 wip: fog for opaques in applied as a post-process effect (#9645)
Instead of computing the fog "inline", in the forward pass, we can
instead compute it as post-process pass that is applied with a
simple fullscreen quad blending.  On tilers, the operation entirely
stays in the tile, on desktop GPU it is a blending operation.

This works only for opaque materials.

The benefit is that fog will become immune to overdraw, and the forward
pass shader will be simplified, hopefully leading to less register
pressure. Overall performance should be improved.

Another benefit is that it will allow us to free the "fog" texture
slot from all opaque materials.

Transparent materials are unchanged.

This feature is currently DISABLED, and still work in progress; but it
should be mostly functional.

To test it:

```
env material.enable_fog_as_postprocess=true ./out/samples/gltf_viewer
```

This change refactor the fog code, but shouldn't have any impact on the
current behavior.
2026-01-30 12:57:25 -08:00
Powei Feng
b40530ad3c imageio-lite: add simple tiff import/export (#9654)
- Add new library to do tiff import/export.  This library is
   different from imageio in that it doesn't pull in additional
   3p libraries.  This reduces binary size and reduces
   complexity in maintaining the android build (which depends
   on libs/viewer).
 - The encode() code has been moved from libs/viewer to
   libs/imageio-lite
 - encode/decode only handles the simplest case of uncompressed
   rgba.
2026-01-30 17:54:14 +00:00
Eliza Velasquez
0131949aff engine: fix stereo and parallel shader compilation
Another thing that got lost in the sea of merge conflicts that plagued the
program cache feature...
2026-01-30 09:30:54 -08:00
Serge Metral
b85d52f727 External sampler bind index bug (#9664)
Patching a fix for the external sampler use case where the same sampler is bound to two different indices. As it stands, the code fails to differentiate between the two layouts.
2026-01-30 00:27:32 +00:00
Eliza Velasquez
53e6cd3126 engine: fix TAA compilation failure 2026-01-29 15:57:47 -08:00
Patrick Ribas
69ae8c491b Bump some uniforms to FL1 minimum (#9639) 2026-01-29 15:42:28 -08:00
haroonq
c35ae6571f Swap logic of how the EGL display is initialized. (#9634)
1. Iterate over system displays using eglQueryDevicesEXT and try to initialize them.
2. If no display initialized, then try to initialize the DEFAULT display.

FIXES=[478925865]
2026-01-29 13:20:10 -08:00
Mathias Agopian
8d07604604 Fix possible buffer overflow in CommandStream (#9661)
Because of an improper boundary check caused a possible unsigned
integer overflow, it was possible to overrun the command stream
buffer in RenderPass::execute().

It would happen when the batch size was larger than the buffer
capacity (usually a few MB). 

FIXES=[474264976]
2026-01-29 11:22:12 -08:00
Mathias Agopian
4c621b83e9 Fix possible buffer overflow in CommandStream (#9661)
Because of an improper boundary check caused a possible unsigned
integer overflow, it was possible to overrun the command stream
buffer in RenderPass::execute().

It would happen when the batch size was larger than the buffer
capacity (usually a few MB). 

FIXES=[474264976]
2026-01-29 09:42:23 -08:00
Patrick Ribas
4abf7cdaba Move eye matrix array to FL1 (#9656) 2026-01-29 08:54:14 -08:00
Filament Bot
9808aa5460 [automated] Updating /docs due to commit ef24164
Full commit hash is ef24164464

DOCS_ALLOW_DIRECT_EDITS
2026-01-29 07:35:58 +00:00
Patrick Ribas
5c15d56cf5 Remove PerRenderableData::reserved from FL0 (#9657) 2026-01-28 23:32:42 -08:00
Mathias Agopian
ef24164464 Improve Moon/Earthshine, add Touch support (#9659)
- Fix Moon normal calculation in shader (was inverted).
- Implement physically based Earthshine (dynamic based on phase).
- Add Moon scattering to Water reflection.
- Fix Star occlusion (masked by Moon).
- Improved Stars
- Add mobile touch support (Orbit control) to Camera.

DOCS_FORCE
2026-01-28 23:32:06 -08:00
Powei Feng
a1abfa30b8 github: use exsiting android native tgz in release (#9651)
However, the change also pulled in filament-android-release-linux.tgz,
which already contains the same content, into the release.

Here we just rename filament-android-release-linux.tgz to the
expected .tgz output file in the release build.

Fixes #9647
2026-01-28 21:29:42 +00:00
Powei Feng
b5abcd9bc1 vk: use proper sync read bit after uploading ubo (#9644)
VK_ACCESS_UNIFORM_READ_BIT is for UBOs where as
VK_ACCESS_SHADER_READ_BIT is for other types of resources.
2026-01-28 19:17:06 +00:00
Powei Feng
8d34af2004 backend: add readTexture api and stubs (#9646) 2026-01-28 18:55:37 +00:00
Powei Feng
db0524d59b imagediff: add image comparison library (#9640)
A library for verifying rendering results against golden images.

Key Features:
- Hierarchical checks (AND, OR, LEAF).
- Per-pixel masking.
- Global failure tolerance (`maxFailingPixelsFraction`).
- 8-bit `Bitmap` support.
- JSON configuration.
2026-01-28 10:35:36 -08:00
Powei Feng
6193f489a3 gltfio: prevent malformed gltf+draco mesh (#9638)
Fix is to move from assert() to FILAMENT_CHECK_PRECONDITION

FIXES=478028329
2026-01-28 18:14:06 +00:00
Filament Bot
fb31759c27 [automated] Updating /docs due to commit 375e3a0
Full commit hash is 375e3a03ec

DOCS_ALLOW_DIRECT_EDITS
2026-01-28 09:29:12 +00:00
Mathias Agopian
375e3a03ec SkySim: add initial support for a moon (#9650)
- also update filament binaries

DOCS_FORCE
2026-01-28 01:25:03 -08:00
Filament Bot
11bf3a4493 [automated] Updating /docs due to commit 7c64fb9
Full commit hash is 7c64fb9cf3

DOCS_ALLOW_DIRECT_EDITS
2026-01-28 07:56:16 +00:00
Mathias Agopian
7c64fb9cf3 SimSky: Optimize URL state sharing and fix UI synchronization (#9649)
- **Key Minification**: Refactored serialization to use short keys
  (e.g., `p`, `c`, `w`) instead of verbose property names, reducing URL 
  size by ~50%.
- **State Optimization**: Removed redundant `sunDirection` from 
  serialized state.
- **Cleanup**: Removed backward compatibility for verbose keys 
- **Bug Fix**: Fixed a regression where UI sliders failed to update on 
  load by ensuring array properties (e.g., `sunHalo`) are mutated 
  in-place rather than replaced.

DOCS_FORCE
2026-01-27 23:52:49 -08:00
Filament Bot
d3de9efc33 [automated] Updating /docs due to commit e9dcf2a
Full commit hash is e9dcf2a63a

DOCS_ALLOW_DIRECT_EDITS
2026-01-28 06:40:54 +00:00
Mathias Agopian
e9dcf2a63a SimSky: Add URL state sharing and configuration persistence (#9648)
- **State Management**:
  - Refactored main.js to expose local UI parameter objects as class
    properties for serialization.
  - Implemented getURLState() to capture complete scene configuration 
    (Sky, Clouds, Water, Stars, Camera, Bloom).
  - Implemented applyURLState() to restore settings and synchronize 
    the UI.

- **URL Sharing**:
  - Added "Share Configuration" button to the UI.
  - Configuration is Base64-encoded into a `config` URL query parameter.
  - App now automatically parses and applies the `config` parameter 
    on startup, allowing for stateful deep linking.

DOCS_FORCE
2026-01-27 22:36:54 -08:00
Doris Wu
8008d21782 turn the checks into assert (#9642) 2026-01-28 05:59:14 +00:00
Powei Feng
852ecf048a filamat: remove unnecessary std::decay_t (#9643) 2026-01-27 18:02:42 -08:00
Filament Bot
3c91c74232 [automated] Updating /docs due to commit 8d20d7a
Full commit hash is 8d20d7abec

DOCS_ALLOW_DIRECT_EDITS
2026-01-27 22:57:02 +00:00
Benjamin Doherty
fafd8f8196 Bump version to 1.69.1 2026-01-27 14:50:29 -08:00
Benjamin Doherty
6242f375ef Merge branch 'rc/1.69.0' into release 2026-01-27 14:50:28 -08:00
Benjamin Doherty
8d20d7abec Release Filament 1.69.0 2026-01-27 14:50:19 -08:00
Eliza
2f1266f7dd engine: add program cache (#9297)
* engine: add program cache

This is another chunky change.

The core of this change is to cache programs in MaterialCache according to a
"specialization" (ProgramSpecialization) which is defined as the program cache
ID (the same key used for the OpenGL binary blob cache), the variant, and the
set of spec constants.

As part of this change, a lot of the implementation details of shader
compilation were refactored from Material to MaterialDefinition. The resulting
flow is a lot cleaner and easier to reason about, since shader compilation is
now a pure function of the MaterialDefinition + ProgramSpecialization.

Since the global cache program lookups might take a bit of time to compute
hashes, etc, I left the set of cached programs in Material as well, which kind
of acts like an L1 cache. The effect is that prepareProgram() and getProgram()
should be no slower than HEAD, even with the more complex caching requirements.

I'm planning on writing a document about this (and all changes up until this
point), but I'm being asked to work on higher priority things and I wanted to
have this PR out for review in the meantime so it doesn't bitrot.

* engine: fix unit tests

* engine: fix spec constants intern pool memory leak

* engine: address program cache comments

* engine: address more program cache comments

* engine: matdbg support for program cache

* engine: reinstate descriptorLayout calls

* engine: address bitrot

* engine: add feature flag to disable program cache

* engine: use material CRC32 for program cache

The "cache ID" of a material is supposed to uniquely identify a shader program
and all its variants. This is true to a certain extent, but does not account for
the code generation that happens at runtime. Two materials may have "identical"
shader programs, but due to each material's differing unique metadata, the final
compiled programs may end up very different. Unfortunately, this means we cannot
rely on the "cache ID" alone to determine a shader program's reusability.

Ideally, we should hash this "cache ID" with the exact set of changes to each
shader program so that we could reuse programs across materials. Instead, as a
stopgap solution, use the material's CRC32 instead.

* engine: fix double-free in program cache

* engine: address comments

* engine: assert_invariant empty material cache
2026-01-27 13:09:42 -08:00
Benjamin Doherty
05be4b0acc Update filament-tools macOS classifier 2026-01-27 11:34:46 -08:00
Mathias Agopian
9d9c3d34f8 Fix a typo that corrupted the tags of descriptor sets and layouts (#9641)
- we were setting the tag of the descriptor set to its layout, so
  both tags were incorrect.

- added in debug build we now store the tag of the bound descriptor
  sets in the current bindings structure.
2026-01-27 10:44:04 -08:00
Powei Feng
491531c76b gltfio: fix possible overflow for meshopt decompression (#9637)
FIXES=478908360
2026-01-27 17:54:36 +00:00
Mathias Agopian
bf4ea771be AtlasAllocator: Implement free() and upgrade to Buddy Allocator (#9635)
This change upgrades AtlasAllocator from a simple linear allocator 
(reset-only) to a full Buddy Allocator capable of both allocation and 
deallocation. This enables persistent shadow map management where 
individual shadow maps can be updated or resized without rebuilding the 
entire atlas every frame.

Key changes:
- Implemented AtlasAllocator::free():
	- Uses the existing QuadTree structure to track allocations.
	- Automatically coalesces empty sibling nodes back into larger 
      parent blocks (standard Buddy Allocator behavior).
	- Optimized to be allocation-free and recursion-free, using direct 
      array indexing.

- Added comprehensive unit tests

Updated documentation.

The QuadTreeArray implementation remains unchanged but is now fully 
utilized for bidirectional tree traversal (down for alloc, up for free).

This change will later allow us to cache shadow-maps.
The AtlasAlocator is currently disabled by a feature flag.
2026-01-27 09:21:20 -08:00
Doris Wu
dd5882760b implement memory mapping for wgpu (#9632)
It is a zero effort implementation where it just calls `updateBufferObject` to update the data.
2026-01-27 03:05:46 +00:00
rafadevai
1707dda62a VK: Only bypass the staging buffer when is not in use (#9633)
In the cases where a frame takes more than the vsync
time, we start seeing some rendering artifacts because
we write to a buffer that is currently in flight.

Not 100% sure why the current approach fails but for
now, the staging buffer is bypassed only when the buffer
is not in use or referenced by any other resource.

FIXED=[445455050]
FIXED=[477305399]
2026-01-26 17:57:56 -08:00
Benjamin Doherty
c4d3eded72 Bump MATERIAL_VERSION to 69 2026-01-26 14:00:12 -08:00
Benjamin Doherty
e1adfa09ba Bump MATERIAL_VERSION to 69 2026-01-26 13:59:23 -08:00
Powei Feng
ca4b0650fa Re-commit "Generalize scene description for automated testing (#9627)"
Contains a fix to the default sunlight parameters that broke the
renderdiff tests.
2026-01-26 13:33:09 -08:00
Powei Feng
33d22b3146 Revert "[automated] Updating /docs due to commit 60b1951" and "Generalize scene description for automated testing (#9627)"
This reverts commit e2dd47bf42.
This reverts commit 60b1951f90.

renderdiff test breakage
2026-01-23 17:20:31 -08:00
Filament Bot
e2dd47bf42 [automated] Updating /docs due to commit 60b1951
Full commit hash is 60b1951f90

DOCS_ALLOW_DIRECT_EDITS
2026-01-24 00:04:44 +00:00
Powei Feng
60b1951f90 Generalize scene description for automated testing (#9627)
- Extended Settings to include properties for Camera, Animation, Lights,
  and Render options.
- Moved camera options from Viewer options to Camera options
- Implemented generic JSON parsing for these new settings in Settings.cpp.
- Updated AutomationEngine to apply these settings, including dynamic
  creation of lights.
- Fixed a JSON parsing bug in AutomationSpec that failed on nested objects.
- Updated gltf_viewer to use the new settings and correctly initialize
  AutomationEngine context.
- Add test for new json changes
- Add README to libs/viewer
- Link libs/viewer/README.md to official doc
- Remove unused libs/viewer/schemas
- Updated remote web assets (because the viewer/settings json needs to
  match)
2026-01-24 00:02:06 +00:00
Filament Bot
6ce06b1b60 [automated] Updating /docs due to commit e21d4a5
Full commit hash is e21d4a5326

DOCS_ALLOW_DIRECT_EDITS
2026-01-23 09:10:02 +00:00
Mathias Agopian
e21d4a5326 SimSky: Refine Stars, Water, and Heat Shimmer simulation (#9628)
- **Stars**:
  - Implemented procedural stars using hash-based noise.
  - Added UI controls for Star Density and Enable/Disable.
  - Tuned star brightness (reduced intensity) and refined twilight fade timing (visible during nautical twilight).
  - Improved compositing with aggressive cloud occlusion and non-linear fade.
  - Added star reflections to water, strictly masked to the horizon line.

- **Heat Shimmer**:
  - Fixed horizon artifacts by decoupling shimmer from atmospheric density (Mie scattering).
  - Implemented FBM-based view distortion for heat waves.
  - Added sun elevation fade (shimmer fades out as sun rises > 30°).

- **Water**:
  - Implemented Finite Difference normal calculation as a high-quality fallback when "Derivative Trick" is disabled.
  - Added "Octaves" parameter to control wave detail.
  - Refined reflection logic to handle stars and sun disk properly.

- **System**:
  - Updated [simulated_skybox.mat](cci:7://file:///Users/mathias/sources/git/filament/docs_src/src_raw/wip/sky/simulated_skybox.mat:0:0-0:0) with new material parameters (`starControl`, `waterControl`).
  - Refactored JS bindings in [SimulatedSkybox.js](cci:7://file:///Users/mathias/sources/git/filament/docs_src/src_raw/wip/sky/SimulatedSkybox.js:0:0-0:0) and organized `main.js` UI into logical folders.

DOCS_FORCE
2026-01-23 01:06:07 -08:00
Doris Wu
81ad84abb6 return empty string for es2 (#9623) 2026-01-23 10:34:57 +08:00
Filament Bot
7fd9e728ae [automated] Updating /docs due to commit b66736b
Full commit hash is b66736b8cc

DOCS_ALLOW_DIRECT_EDITS
2026-01-22 23:23:09 +00:00
Powei Feng
b66736b8cc docs: move wip skybox demo to /docs_src/src_raw (#9626)
/docs content is overwritten by content in /docs_src

(This tag will force a regeneration)
DOCS_FORCE
2026-01-22 23:20:10 +00:00
Doris Wu
ea8f6a3c92 return empty string for es2 (#9623) 2026-01-22 14:49:54 -08:00
Doris Wu
adcdbb45f9 fix typo (#9625) 2026-01-22 14:49:38 -08:00
Mathias Agopian
cff958587d initialize VirtualMachineEnv on the right thread (#9624)
PerformanceHint manager needs a java thread during initialization,
so we need to attach a jvm to the thread that's going to be used.
That thread is the filament backend thread, not necessarily the thread 
the platform is created on.

So we make sure to do that from the backend thread.


FIXES=[427945768]
2026-01-22 10:24:39 -08:00
Mathias Agopian
9ab2326f15 some work in progress sample 2026-01-22 00:50:35 -08:00
Anish Goyal
8785acd352 Fix push constants with ext sampler (VK) (#9445)
Currently, in Vulkan, we set the pipeline layout when binding the
pipeline, which doesn't happen until draw time when external samplers
are present. In cases like that, we push constants with the layout
VK_NULL_HANDLE, which is not valid. Instead, we can wait until the
pipeline layout is known, and then flush all push constants.
2026-01-22 08:15:20 +00:00
Mathias Agopian
57767b7f27 Fix buffer overflow in RenderPass command batching (#9619)
The command batching logic in RenderPass::Executor::execute calculates a
conservative `maxCommandSizeInBytes` to determine how many commands can
safely fit in the driver's circular buffer.

However, this calculation failed to account for the dynamic memory
allocation incurred by the Per-Material descriptor set binding (via
`MaterialInstance::use`). This binding allocates a `DescriptorSetOffsetArray`
in the command stream, which was unbudgeted.

In scenarios with frequent material and scissor changes, the accumulated
deficit from these unbudgeted allocations could exceed the buffer 
capacity, leading to a crash.

This change:
1. Adds the missing accounting for the Per-Material dynamic allocation 
   to `maxCommandSizeInBytes`.
2. Adds a 20% safety margin to the calculated size to robustly handle
   alignment padding and worst-case scenarios.


FIXES=[474264976]
2026-01-21 21:03:49 -08:00
Powei Feng
febcfc8f2d fgviewer: add info in panel for render passes (#9618)
- Add plumbing to add more information about rendertargets
   (including discard flags and pass id) to the fgviewer pass
   struct.
 - Add UI to display information about a selected pass
 - Highlight a selected resource or pass
2026-01-22 03:39:20 +00:00
Filament Bot
c04c387a89 [automated] Updating /docs due to commit 78ac946
Full commit hash is 78ac9467f8

DOCS_ALLOW_DIRECT_EDITS
2026-01-22 03:05:41 +00:00
Sungun Park
5dc095782a Merge branch 'rc/1.68.5' into release 2026-01-21 19:01:36 -08:00
Sungun Park
2162e6d01f Bump version to 1.69.0 2026-01-21 19:01:36 -08:00
Sungun Park
78ac9467f8 Release Filament 1.68.5 2026-01-21 19:01:22 -08:00
Romain Guy
73b60d4db8 Add a new tone mapper (#9614)
The new tone mapper, dubbed "GT7" in the code, is based on
the Gran Turismo 7 tone mapper, as described in the SIGGRAPH
2025 presentation called "Driving Toward Reality: Physically
Based Tone Mapping and Perceptual Fidelity in Gran Turismo 7".

This tone mapper exhibits fewer hue skews than the other tone
mappers, at the exception of PBR Neutral. The GT7 tone mapper
is however better at preserving the perception of high
dynamic range.

The tone mapper, as implemented, targets an SDR paper white
of 250 nits, using 100 cd/m^2 as the reference luminance (for
values of 1.0 in the linear HDR framebuffer). This can result
in an overall darker image compared to the other tone mappers
but this can be controlled through camera settings, post-
processing exposure, or lighting intensity.

The GT7 tone mapper also allows to target HDR output, and
could be made customizable via APIs if desired. The current
implementation offers a fixed aesthetic solution.
2026-01-21 17:31:27 -08:00
Ben Doherty
7266fd67db Add filament-tools subproject (#9622) 2026-01-21 15:22:39 -08:00
Filament Bot
469f2c94da [automated] Updating /docs due to commit d4e0d05
Full commit hash is d4e0d051b1

DOCS_ALLOW_DIRECT_EDITS
2026-01-21 22:26:09 +00:00
Powei Feng
d4e0d051b1 docs: make docs more consistent and complete (#9620)
- Add documentation for specgen along with proper math rendering
- Adjust the heading size, capitalization of various READMEs.
- Add backend test README to the doc
- Rename the CI related tests to have prefix "CI:"
2026-01-21 22:22:12 +00:00
Ben Doherty
df74a5a352 Re-enable iOS filamat builds (#9598) 2026-01-21 19:30:00 +00:00
Doris Wu
21fd32266a Add support for custom morphing (#9550)
BUGS=[443321184]
2026-01-21 17:11:35 +08:00
Sungun Park
cd7c7b369b Add helloasync sample (#9617)
Introduces a new sample application demonstrating asynchronous resource
management. It shows how to asynchronously create and update Filament
resources (Textures, VertexBuffers, IndexBuffers) and provides examples
of managing chains of asynchronous operations effectively.

BUGS=[442921995]
2026-01-21 00:38:08 +00:00
Powei Feng
65ed7099c0 fgviewer: UI updates (#9615)
- Pick a default view when database is filled.
 - Fix d3, d3-graphviz depdency.
 - reduce the size into a smaller table (to avoid scrolling)
 - slant the pass items to allow smaller cells for the table.
 - make subresource rendering the same as regular resource
   rendering with a color hint.
 - Use color-only to indicate resource/pass interaction (read,
   write, read-write, no-access)
 - add tooltip to indicate resource action
2026-01-20 21:02:23 +00:00
Anish Goyal
6e17c413b9 Fix race condition for cache prewarming (#9613)
Right now, if a material is destroyed just after creation, it's possible
for prewarm to attempt to use destroyed shader modules. This ensures
that the resources are kept until after any queued jobs have run.

While it is likely ideal to properly cancel the prewarm if the program
has been destroyed, this seems like a rare occurrence in practice.
2026-01-20 12:36:44 -08:00
rafadevai
e0bcec5ef3 VK: Add support for VK_KHR_global_priority (#9607)
Add support for application that want to change the
priority of GPU queues at a system level.
2026-01-20 12:36:39 -08:00
rafadevai
af34572883 VK: Add support for VK_KHR_global_priority (#9607)
Add support for application that want to change the
priority of GPU queues at a system level.
2026-01-20 19:53:55 +00:00
Anish Goyal
1f6a67b2a2 Fix race condition for cache prewarming (#9613)
Right now, if a material is destroyed just after creation, it's possible
for prewarm to attempt to use destroyed shader modules. This ensures
that the resources are kept until after any queued jobs have run.

While it is likely ideal to properly cancel the prewarm if the program
has been destroyed, this seems like a rare occurrence in practice.
2026-01-20 18:04:34 +00:00
Sungun Park
7701e7a65a Handle deferred destruction for asynchronous objects (#9604)
When an asynchronous object is destroyed immediately after creation, the
background creation process may still be active, holding a reference to
the object. We now defer destruction in these cases until the creation
process completes to ensure the reference remains valid.

Implementation details:
1. Add a mechanism to stop the ServiceThread to drain pending
   asynchronous tasks earlier. This ensures the mCreationComplete flag
   in the frontend object is set to true.
2. Later, the engine's terminate performs garbage collection for the
   deferred destruction. All of them must be successfully processed.

BUGS=[442921995]
2026-01-17 02:44:28 +00:00
Filament Bot
65a91832a8 [automated] Updating /docs due to commit acb47ff
Full commit hash is acb47ffed5

DOCS_ALLOW_DIRECT_EDITS
2026-01-16 00:26:35 +00:00
Powei Feng
88f4f3d4c2 Merge branch 'rc/1.68.4' into release 2026-01-15 16:21:46 -08:00
Powei Feng
61f3f7f4d8 Bump version to 1.68.5 2026-01-15 16:21:46 -08:00
Powei Feng
acb47ffed5 Release Filament 1.68.4 2026-01-15 16:21:37 -08:00
Filament Bot
13c0304d84 [automated] Updating /docs due to commit febdf39
Full commit hash is febdf3974c

DOCS_ALLOW_DIRECT_EDITS
2026-01-15 23:24:29 +00:00
Powei Feng
febdf3974c docs: improve release and test documentation (#9609)
- Reorder the release-related documents into one heading.
 - Added CocoaPods README as part of the documentation.
 - Fixed typo for renderdiff doc
 - Added backend test doc
2026-01-15 23:22:00 +00:00
Powei Feng
390acec928 vk: add feature flag for acquiring swapchain in makeCurrent (#9610)
Removing this behavior in #9541 caused a breakage in one of our
clients. We use a feature flag to enable the old behavior.

BUGS=476144715
2026-01-15 22:48:12 +00:00
Powei Feng
ff806f8c3e Misc fixes to address old compiler errors (#9611)
Certain older compilers (e.g. clang in NDK 25.1.8937393) cannot
handle the c++ stylistic changes that were recently added
(though they are correct by spec).

 - In Engine.cpp, .find() cannot automatically infer the right type
   (std::string_view vs. utils::CString).
 - In fg/framegraph, various templated short-hands still require
   typename.
2026-01-15 20:27:26 +00:00
Powei Feng
06c4faabc3 vk: disable pushconstant backend test for CI
Due to flakiness.
2026-01-15 11:36:46 -08:00
Powei Feng
92aec16fa3 Add comment to indicate TextureFormat value (#9608)
This will help with debugging if we needed to print out a
TextureFormat value.
2026-01-15 19:21:39 +00:00
Mathias Agopian
f1ffb783d8 feat(engine): Add automatic frame skipping to manage CPU/GPU latency (#9595)
* feat(engine): Add automatic frame skipping to manage CPU/GPU latency

Introduces a new feature, disabled by default, that allows the engine to automatically skip frames when the CPU gets too far ahead of the display's refresh rate. This helps to reduce overall latency by preventing a backlog of frames from building up in the driver queue.

The feature can be enabled with the "engine.skip_frame_when_cpu_ahead_of_display" property.

To implement this, the compositor timing mechanism has been refactored. Instead of reporting an absolute `expectedPresentTime`, the backend now provides an `expectedPresentLatency` relative to vsync. This is more robust against synchronization issues with platform callbacks (like Android's Choreographer), as the latency is generally a constant value.

BUGS=[474599530]
2026-01-15 09:50:56 -08:00
Mathias Agopian
b708300586 Refactor implicit DriverApi dependency (#9606)
Removed implicit dependency on FEngine::getDriverApi() in critical 
rendering paths. This change makes the DriverApi dependency explicit by 
passing it as a parameter.


Key changes:

- FRenderer: Now accepts DriverApi& in renderInternal and renderJob. 
Caches feature levels and capability flags in the constructor.

- PostProcessManager: Caches feature flags and workaround flags in 
init(). Updated PostProcessMaterial and configure* methods to accept 
DriverApi&.

- FMaterial: Caches support flags (stereo, parallel shader compile) and
default material pointer in the constructor. 
Updated precacheDepthVariants and prepareProgram to rely on these 
cached values or passed parameters.

- ShadowMapManager: Caches workaround flags in the constructor.

- FEngine: Updated prepare() to accept DriverApi&.

- RenderPass: Updated to accept DriverApi& in constructor and 
appendCommands.

- Removed implicit DriverApi calls from hot paths to reduce overhead 
and improve safety.


One common pattern in this change is to cache getters in constructors
so that we don't need the DriverApi dependency later during rendering.
The intention here is to remove DriverApi& from as many places as
possible so that we can later have multithreading for command
recording.

This PR should not change any behavior.
2026-01-15 09:11:12 -08:00
HanYunChenLuo
f88d757d06 Add glibc check to support build filament on Linux musl-based distrib… (#9592) 2026-01-14 23:22:07 +00:00
Powei Feng
4d96f188d1 backend: CallbackHandler dstor inlined in header (#9605)
Defining the destructor in a cpp will break downstream clients.

The previous move to cpp was part of #9508.
2026-01-14 22:22:10 +00:00
Powei Feng
2d943f40bb vk: fix push constant implementation and test (#9588)
All stages share a push constant "block". We need to order
the fragment stage bytes to after the vertex stage if they
both exists.

FIXES=453776664
2026-01-14 18:18:04 +00:00
Doris Wu
92c058a736 fix gtao shader on mobile (#9591) 2026-01-13 14:11:34 +00:00
Mathias Agopian
ba819bcfca Docs: Improve documentation in public headers (#9603)
This commit clarifies and corrects documentation in several public header
files. The changes include fixing typos, improving wording, and adding
missing details to make the API easier to understand and use.

No functional changes are included in this commit.
2026-01-12 14:31:42 -08:00
Mathias Agopian
e22f1adfa7 make "native streams" deprecated (#9602)
Co-authored-by: Powei Feng <powei@google.com>
2026-01-12 14:31:15 -08:00
Anish Goyal
c03276f38a Add external format to cache prewarming (#9558)
Provides logic to load and check for external format ids, and
build fake pipelines against them when relevant, to prevent
hitching when using external formats.

For now, we're going to use upto five likely types of YCbCr
conversions, which seem to cover all usecases encountered. This
means we might compile pipelines with external samplers a total of
4 additional times on top of the baseline (5 in total), or 3 additional
times on the devices we're currently testing (4 in total).

* Add base pipeline prewarm call for ext samplers

This is necessary because in some cases, a material that supports
external samplers will use RGB inputs instead of YCbCr inputs, and will
miss the cache.
2026-01-12 13:08:08 -08:00
Anish Goyal
f2bca03360 Add external format to cache prewarming (#9558)
Provides logic to load and check for external format ids, and
build fake pipelines against them when relevant, to prevent
hitching when using external formats.

For now, we're going to use upto five likely types of YCbCr
conversions, which seem to cover all usecases encountered. This
means we might compile pipelines with external samplers a total of
4 additional times on top of the baseline (5 in total), or 3 additional
times on the devices we're currently testing (4 in total).

* Add base pipeline prewarm call for ext samplers

This is necessary because in some cases, a material that supports
external samplers will use RGB inputs instead of YCbCr inputs, and will
miss the cache.
2026-01-12 19:32:01 +00:00
Ben Doherty
5f07d701f0 Fix CocoaPods build (#9597) 2026-01-12 10:20:51 -08:00
Mathias Agopian
496a50bc89 make getWorldFromModelMatrix() accessible in fragment shader (#9584)
this requires to specify `apiLevel: 2` in the material.

FIXES=[474353927]
2026-01-12 09:32:23 -08:00
Mathias Agopian
6ccb6c4cce split FeatureFlagManager out of FEngine (#9596)
* split FeatureFlagManager out of FEngine

- Separate the Feature flags management from FEngine.
- Make FeatureFlagManager available to backends through DriverConfig
- add a way to override a feature flag value at runtime using
  environment variables or system properties (on Android).

e.g.:

```
env "feature.name=true" gltf_viewer
```
or 
```
adb shell setprop debug.feature.name true
```

Co-authored-by: Powei Feng <powei@google.com>
2026-01-12 09:31:51 -08:00
Powei Feng
42c78fd0a9 github: refactor postsubmit CI tasks into single yml (#9587) 2026-01-12 17:28:53 +00:00
Doris Wu
3d0e2923ae Fix VB-GTAO on remote webui (#9599) 2026-01-12 19:10:30 +09:00
Mathias Agopian
408b2371f0 allow FILAMENT_TRACING_CALL to take extra parameters (#9593) 2026-01-09 15:08:27 -08:00
Powei Feng
6ea08b40a8 gl: small fixes to push constant implementation and test (#9594)
- Add code for handling empty/null constant name
 - Use glUniform1ui() instead of glUniform1i() to workaround
   crash on macbook pro (m4).
 - Fully specify the constant name in the test (e.g.
   `pushConstantsF.red` instead of `red`).
 - Make sure that the uniform names are different between
   vertex and fragment in the test. This is due to different
   constant structs being defined between the two stages.

FIXES=453757504
2026-01-09 14:48:52 -08:00
Doris Wu
5eb0f7d3ec Fix the vbotest sample (#9581)
* set clear to true

* feedback
2026-01-09 10:15:44 +08:00
Powei Feng
d465d59c3a github: run filament tests in presbumit (#9586) 2026-01-08 21:25:58 +00:00
Filament Bot
af9a60d175 [automated] Updating /docs due to commit 8e0f0c9
Full commit hash is 8e0f0c92ce

DOCS_ALLOW_DIRECT_EDITS
2026-01-08 20:19:49 +00:00
Benjamin Doherty
f98b76f99f Bump version to 1.68.4 2026-01-08 12:14:16 -08:00
Benjamin Doherty
f88d3ed278 Merge branch 'rc/1.68.3' into release 2026-01-08 12:14:15 -08:00
Benjamin Doherty
8e0f0c92ce Release Filament 1.68.3 2026-01-08 12:14:07 -08:00
Anish Goyal
5a14fb4b5d Cache prewarm base case (#9552)
Prevents hitching for most pipelines, on certain devices with Turnip-based drivers

This does not address external samplers yet. This simply handles the
case where we want to prewarm a pipeline with the base configuration.

Refactor program's descriptor set layout bindings, clean up some leaking
resources
2026-01-08 11:43:32 -08:00
dependabot[bot]
22a1aacb21 Bump urllib3 in /docs_src/build in the pip group across 1 directory (#9585)
Bumps the pip group with 1 update in the /docs_src/build directory: [urllib3](https://github.com/urllib3/urllib3).


Updates `urllib3` from 2.6.0 to 2.6.3
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.6.0...2.6.3)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.6.3
  dependency-type: direct:production
  dependency-group: pip
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-08 18:48:08 +00:00
dependabot[bot]
e5b6c11399 Bump urllib3 in /test/renderdiff/src in the pip group across 1 directory (#9582)
Bumps the pip group with 1 update in the /test/renderdiff/src directory: [urllib3](https://github.com/urllib3/urllib3).


Updates `urllib3` from 2.6.0 to 2.6.3
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.6.0...2.6.3)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.6.3
  dependency-type: direct:production
  dependency-group: pip
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-08 10:28:15 -08:00
Mathias Agopian
85ebd67a28 feat(taa): Overhaul TAA implementation for improved quality and upscaling (#9573)
This commit introduces a significant rework of the Temporal Anti-Aliasing (TAA) system, focusing on improving reconstruction quality, robustness, and introducing flexible upscaling.

Core TAA Algorithm improvements:
- Replaced the Catmull-Rom filter with a more efficient 5-tap Lanczos filter for history sampling, which includes deringing to reduce artifacts.
- The input color buffer is now properly "unjittered" using a Lanczos reconstruction filter.
- Improved the history rejection algorithm by skipping the expensive accurate clipping when the history sample is already within the neighborhood's color gamut.
- Added a new `hdr` option to properly handle HDR content by tonemapping colors before blending and untonemapping the result.
- Removed the ineffective `VARIANCE` only history rejection method.
- Added protection against negative numbers in `sqrt()` for increased stability.

TAA Upscaling:
- Replaced the boolean `upscaling` flag with a float factor, allowing for variable upscaling ratios (e.g., 1.5x, 2x).
- Upscaling now correctly adjusts viewport and projection settings.
- The TAA shader now receives viewport and resolution information to correctly handle upscaled rendering.

API and Configuration Changes:
- Deprecated the `filterWidth` TAA option as it no longer has an effect.
- Introduced the `upscaling` float property to `TemporalAntiAliasingOptions`.
- Added the `hdr` boolean property to `TemporalAntiAliasingOptions`.

Other Changes:
- Updated UI elements in the viewer and material sandbox to reflect the new TAA options.
- Updated Javascript bindings and TypeScript definitions for the new TAA settings.
- Refactored shader code for clarity and performance.
2026-01-07 15:25:38 -08:00
Powei Feng
f33a779668 vk: move swapchain acquire() to as late as possible (#9541)
makeCurrent is not meant to acquire the swapchain; we should
do so at the momemnt we need it, to shorten the amount of time
a swapchain image/buffer needs to be held.
2026-01-07 18:36:54 +00:00
Sungun Park
1b5916b655 Rename AsyncCallbackType to AsyncCompletionCallback (#9579) 2026-01-07 18:18:49 +00:00
Anish Goyal
d8720cd858 Rename DescriptorSetLayoutBinding to DescriptorSetLayoutDescriptor (#9576)
Since the struct refers to descriptors as opposed to specifically
bindings (although they do contain binding information as well), this
name is more appropriate.
2026-01-07 16:52:50 +00:00
Doris Wu
44636bddaa Split Skinning out of Visibility struct (#9575) 2026-01-07 11:37:42 +08:00
Sungun Park
1741723687 Add user parameter to runCommandAsync (#9577) 2026-01-06 18:37:42 -08:00
Mathias Agopian
ad2c291d4a dispersion in XYZ space (#9572)
- spectral reconstructions with 4 samples
- unroll the whole dispersion computation to improve performance
  (batch texture fetches and reuse common values)
- tool to generate the matrices for spectral integration
2026-01-06 16:58:56 -08:00
Mathias Agopian
52ffd80041 Refactor FrameGraph pass API for flexibility (#9571)
This commit simplifies and unifies the FrameGraph's `addPass` API.
Key changes:
- The `addPass` method now uses a single, more flexible implementation
  that handles different lambda signatures for both the setup and
  execute stages.
- The execute lambda can now optionally omit the `DriverApi&` parameter,
  reducing boilerplate for simple passes.
- The `addTrivialSideEffectPass` helper has been removed.
  Side-effect-only passes can now be created directly with `addPass`
2026-01-06 14:20:47 -08:00
Doris Wu
44dde744ea Several optimizations for UBO batching (#9545) 2026-01-06 05:52:32 +00:00
Mathias Agopian
c18ddf929e Improve frame_generator sample tool (#9570)
- Add support for vector parameters (float2, float3, float4) in the 
  parameters file using `{x, y, z}` syntax.
- Allow comments (`#`, `//`) and empty lines in the parameters file.
- Make the end value optional in the parameters file 
  (defaults to start value).
- Add `--size` / `-S` option to specify viewport dimensions.
- Optimize rendering by pre-filtering active material parameters.
- Remove hardcoded default parameters and silently ignore missing 
  parameters to support shared configuration files.
- Add documentation for the parameters file format.
2026-01-05 20:28:04 -08:00
Mathias Agopian
5661365248 improved the dispersion computation (#9544)
- Split the function so that the 3-components loop is more apparent.
- Factored out the parts of the computation that don't depend on the
index of refraction, so they're only computed once.
- Moved the lod-from-roughness computation out of the loop as well. 
  It does depend on the IOR, but so little that it's not worth it.

The most important result of this change is that the code is now in
good shape if we wanted to change the implementation of dispersion for
these cases (for e.g.) :
- do the computation in the XYZ space
- use more than 3 wavelengths samples
- or use a stochastic approach, trading banding for noise

RDIFF_BRANCH=ma/better-dispersion
2026-01-05 20:27:34 -08:00
Powei Feng
bcb9d258c2 vk: fix broken android build (#9574)
Should use VK_NULL_HANDLE instead of nullptr where applicable
in VulkanPipelineCache.
2026-01-05 20:27:07 -08:00
Anish Goyal
53a94c4547 Add thread pool and callback manager / knobs for enabling + disabling prewarm (#9515)
* Update createPipeline to have pipeline key input
Right now, createPipeline in VulkanPipelineCache assumes that you are
building a pipeline using mPipelineRequirements as the key, and that it
should be stored in the cache. In the case of the pipeline prewarming
change, this is not going to be the case; sometimes, the pipeline will
be stored in the cache, and sometimes it will be deleted immediately.
Also, the prewarmed pipelines will be created using separately defined
keys.

* Add knobs for enabling / disabling prewarm

* Add thread pool to VulkanPipelineCache

* Fix dynamic rendering enablement check
Query device features to ensure it is supported / we don't just have the
extension. Also, proactively enable dynamic rendering when creating the
device.
2026-01-05 23:55:08 +00:00
Filament Bot
928ffe94a7 [automated] Updating /docs due to commit dcb78c7
Full commit hash is dcb78c7144

DOCS_ALLOW_DIRECT_EDITS
2026-01-05 21:56:49 +00:00
Mathias Agopian
dcb78c7144 update dispersion documentation (#9567)
* add dispersion parameter to material_sandbox

* frame_generator fixes

- fix skybox
- for baseColor to white (workaround)

* update dispersion documentation source
2026-01-05 13:54:24 -08:00
Sungun Park
43dd8fa1cc Fix MockDriver (#9569)
This is missing changes from
0eff54b807
2026-01-05 21:08:50 +00:00
Anish Goyal
91a5f00d30 Remove unnecessary log statement (#9568)
It is not an error for a device to not have this API.
2026-01-05 12:41:34 -08:00
Sungun Park
0eff54b807 Add async support check to backend (#9542)
BUGS=[442921995]
2026-01-05 20:10:36 +00:00
Lucas Leandro
68eb0ce3f1 Add java bindings for changing from default to screen-space reflection in real-time MaterialBuilder (#9548) 2026-01-05 11:44:54 -08:00
Benjamin Schulz
023318c08d Fixes "error: templates must have C++ linkage" when compiling with older clang versions. (#9562)
Co-authored-by: Sungun Park <sungunpark@google.com>
2026-01-05 11:43:54 -08:00
rafadevai
c0e3aa2b0a VK: In UMA, apply the staging bypass for everything (#9538)
Currently only uniform buffers benefit from the bypass,
but this can also be extended to others buffers too.

This also help trying to match the performance of the
GL backend in Android.

FIXES=[470138463]

Co-authored-by: Serge Metral <sergemetral@google.com>
2026-01-05 11:36:54 -08:00
Anish Goyal
a6d1b9188f Add descriptor set layouts to Program (#9522)
This will help later for parallel compilation
2026-01-05 18:59:07 +00:00
Sungun Park
43193c5ac5 Add missing async destruction for BufferObject and IndexBuffer (#9565)
As with Texture, now BufferObject and IndexBuffer will be destroyed via
the async queue if they were asynchronously created.

BUGS=[442921995]
2026-01-05 18:15:01 +00:00
Mathias Agopian
35c58047ee move the depth clear prepare into the framegraph (#9549)
depth clear prepare was done outside of the framegraph, it's now
moved into the colorpass prepare pass.
2026-01-03 15:04:51 -08:00
Mathias Agopian
2190f3544f fix build when FILAMENT_SUPPORTS_VULKAN is OFF (#9557) 2026-01-03 15:03:30 -08:00
Mathias Agopian
fd8ea78e04 Fix TAA (#9556)
TAA had been broken for a while, the jitter was no longer applied.

We now compute the jittered camera before we set it into the 
per frame UBO.
2026-01-03 15:03:06 -08:00
Emily Banerjee
7fc336a6d9 Fix GCC type mismatch error in Platform::debugUpdateStat (#9563) 2026-01-02 09:48:28 -08:00
yein
3cc6fae5c0 Add api level enforcement (#9561)
Api level is now enforced when generating code by appending #defines of client requested and unstable apis.
This ensures that the client can only use unstable apis when they explicitly add `apiLevel` in their .mat file.

FIXES=468340631
2025-12-29 13:38:02 -08:00
yein
f4f75da016 Fix garbage data getting added to the source material (#9553) 2025-12-26 09:29:13 -08:00
Filament Bot
bdeba1aa86 [automated] Updating /docs due to commit 8991be4
Full commit hash is 8991be4eea

DOCS_ALLOW_DIRECT_EDITS
2025-12-24 00:55:04 +00:00
Ben Doherty
8991be4eea Fix incorrect GLSL types in Materials documentation (#9555) 2025-12-23 16:52:27 -08:00
yein
940b93ceb8 Replace slog to LOG (#9554) 2025-12-23 13:45:42 -08:00
Filament Bot
00eb3d0d4f [automated] Updating /docs due to commit 7f61eb7
Full commit hash is 7f61eb7a0a

DOCS_ALLOW_DIRECT_EDITS
2025-12-23 19:44:04 +00:00
Benn Herrera
7f61eb7a0a GLTFIO Webp Texture Support (#9406) 2025-12-23 11:40:01 -08:00
yein
53f506670c Add apiLevel and add parsing logic (#9535) 2025-12-22 13:52:32 -08:00
Mathias Agopian
9fe7ab31ed Make FrameGraph resource management extensible (#9536)
* rename ResourceAllocator to TextureCache

This better represents what this class is for.

* Make FrameGraph resource management extensible

This refactors the FrameGraph's resource management to allow for 
user-defined custom resources.
 
A new `ResourceAllocator` template abstracts the creation and 
destruction of resources, with specializations for different resource 
types (e.g., generic, backend-dependent, textures). 
This removes hardcoded resource management logic from the `FrameGraph` 
execution loop.
 
A `ResourceCreationContext` is introduced to provide the necessary 
context for resource allocation.
 
Tests for generic and backend custom resources have been added to 
validate the new system.

* Update filament/src/fg/FrameGraphDummyLink.h

Co-authored-by: Powei Feng <powei@google.com>

---------

Co-authored-by: Powei Feng <powei@google.com>
2025-12-22 11:08:53 -08:00
yein
5f13abd0bd Fix missing dep in CompressedStringChunk (#9534) 2025-12-22 12:07:33 -07:00
Mathias Agopian
008534b8a2 Fix dispersion with uber-shaders (#9543)
Fixes #9540
2025-12-22 10:12:54 -08:00
Sungun Park
2c5842f908 Implement asynchronous resource management (#9508)
This commit introduces async methods and functions across both the
public and backend APIs, enabling non-blocking creation and updates for
Texture, VertexBuffer, and IndexBuffer resources.

Asynchronous resource management is disabled by default. Users should
enable this to use the feature.

Java bindings and a C++ code sample will follow in subsequent PRs.

BUGS=[442921995]
2025-12-19 21:18:32 -08:00
Powei Feng
a8ee9d473e android: fix texture rendertarget sample for vk (#9528)
- add a flag to run the sample using regular, non-external
   texture as render target.
 - Add a non-external version of the material
 - vk: fix y-flipping issue with uvToRenderTargetUV()
2025-12-19 22:15:22 +00:00
Mathias Agopian
1e3ab83e6a Remove the dependency of RenderPassBuilder on DriverApi (#9533)
The main goal of this CL is to break the dependency of RenderPassBuilder
on DriverApi. The dependency only existed for the auto-instancing 
feature, which needed to allocate and update a UBO on the fly.

We want to break that dependency so that RenderPassBuilder::build().
which is an expensive call, could run on a separate thread. In the
future this could allow, for example, shadow and ssao passes to 
run in parallel.

A new method RenderPass::finalize(DriverApi&) is added which *must* be 
called before calling getExecutor(), this is where the temporary
UBO is allocated and updated. We need a new method because this must be 
called on the main thread before a render pass is started.

This implementation stores the UBO data needed for instancing until
finalize() is called, if any.

We introduce a compact() utility that efficiently scans a range finding
"equivalent" consecutive objects and removes duplicates. The previous
code did that with an extra remove pass which invalidated all 
iterators.
2025-12-19 13:50:20 -08:00
yein
9720da2c68 Fix Json lexeme trying to allocate a string with a huge size due to underflow (#9539) 2025-12-19 13:29:01 -08:00
yein
ee74e2d50c Fix missing dep in CompressedStringChunk (#9534) 2025-12-18 13:35:49 -08:00
Powei Feng
6171009add test: fixing broken webgpu+android build (#9529)
The build was failing because the some tint libs are no longer
real dependencies

Fixes #9520
2025-12-18 18:16:21 +00:00
Mathias Agopian
d299a444fa don't limit FILAMENT_ENABLE_COVERAGE to DEBUG builds (#9532) 2025-12-18 09:24:19 -08:00
rafadevai
107276e9cc VK: Refactor platform Vulkan initialization (#9523)
* VK: Refactor platform Vulkan initialization

Refactor the platform code to allow overriding
how the vkInstance, vkPhysicalDevice and vkDevice
are created.

This refactor will also consolidate where the extensions
and features are enabled/disabled into VulkanPlatform,
instead of each platform doing its own individual setup
if needed. It also address knowing if a feature or
extension has been enabled, unless we keep adding
entries to the SharedContext which is not scalable.

The createDriver function now have a more defined structure,
mostly how and where features are queried and enabled.

- Get shared context data.
- Create instance if missing.
- Select physical device if missing.
- Query physical device support and set supported
engine features into the VulkanContext.
- Select the queues
- Create the device and queues

* Address review comments

Added some documentation on the new functions
Move the querying and config of features into its
own function.
2025-12-18 09:23:18 -08:00
Mathias Agopian
fe00cbf106 feature flags now default to const. (#9530)
This PR doesn't update most of the existing flags that are marked as
"mutable", they're probably wrong.
2025-12-17 10:34:31 -08:00
Filament Bot
02d0ddbcfe [automated] Updating /docs due to commit c4802f7
Full commit hash is c4802f7683

DOCS_ALLOW_DIRECT_EDITS
2025-12-16 23:01:53 +00:00
Sungun Park
78944b4062 Bump version to 1.68.3 2025-12-16 14:57:49 -08:00
Sungun Park
8167baf7e0 Merge branch 'rc/1.68.2' into release 2025-12-16 14:57:48 -08:00
Sungun Park
c4802f7683 Release Filament 1.68.2 2025-12-16 14:57:34 -08:00
Ben Doherty
b582b2d64e Revert "Set the minimum required Metal version (#9425)" (#9527)
This reverts commit f5071b2aae.
2025-12-16 19:54:24 +00:00
Ben Doherty
9c4edf56ca Metal: fix compiler crash when running iOS apps under Mac Catalyst (#9524) 2025-12-16 10:41:14 -08:00
Mathias Agopian
e24fdb3a9d Workaround for harmless warning about descriptor sets (#9519)
* Workaround for harmless warning about descriptor sets

The proper fix is difficult and will be handled later. Here we simply
suppress the warning at FL0.


BUGS=[468072646]

* Apply suggestions from code review
2025-12-15 13:11:00 -08:00
Sungun Park
05f24516dd Fix Build.builder.feature() for Java bindings (#9517)
The "const char*" used for the string literal parameter of the `feature`
method becomes invalid once it passes outside the Java binding scope,
leading to invalid data access. This fix ensures the string is safely
stored.

Add support for heterogeneous lookup in associative containers that
use CString keys. Add conversion operators for std::string_view and
raw string literals to CString.
2025-12-15 21:04:36 +00:00
Mathias Agopian
a3708b2616 fix mat33 in UBOs at feature level 0 (#9510)
When emulating UBOs for feature level 0, we need to use packed
mat33 as source of glUniformMatrix3fv which doesn't expect the std140
alignments of UBOs.

FIXES=[468092808]
2025-12-15 12:43:25 -08:00
Powei Feng
ee514df722 docs: fix freezing when generating docs (#9521)
For reasons unknown, selenium will freeze when trying to make
request to the local server serving the markdown files. We add
a delay between the server and the selenium driver to hopefully
address this.

DOCS_FORCE
2025-12-15 10:50:00 -08:00
Run Yu
924c416644 webgpu: refactor WebGPUPlatform (#9516)
webgpu: refactors WebGPU Platform so each OS environment has its own WebGPU Platform 
class derived from the same base, and use virtual functions for their own implementations.
2025-12-12 19:24:41 -05:00
Powei Feng
597cf9a3ae docs: fix broken markdeep generation (#9514)
The breakage is due to breaking changes in the latest version.
We use the repo checked-in version instead.

Also make sure postsubmit.sh script exits on any error
2025-12-12 23:02:28 +00:00
Powei Feng
316c8376d3 Revert "[automated] Updating /docs due to commit f701c1e"
This reverts commit c300f77151.
2025-12-12 14:27:17 -08:00
Patrick Ribas
672ddddafc Added material name to createParser error logs (#9505) 2025-12-12 14:20:39 -08:00
Mathias Agopian
a8ee48c4b7 a series of CL to add RenderTarget support for external textures (#9504)
* add support for AHardwareBuffer to the java bindings

Texture.setEXternalIamge() now can take a AHArdwreBuffer Java object
as a parameter.

* add an API to set the priority of the Skybox

by default the skybox is always drawn last (priority 7) in order to
reduce overdraw. however, when depth culling is not enabled, it
needs to be drawn first. The new Builder::priority() allows to set
an arbitrary priority for the skybox.

* add rendertarget support for external textures

This was in fact mostly already supported, we just were artificially
preventing that usage. It is supported by the EGL_external_image
extension.

It's the responsibility of the caller/user to not attempt to use an
incompatible format, which has undefined behavior.

FIXES=[466395306]

* add a new android sample to test the AHardwareBuffer as render target

---------

Co-authored-by: Powei Feng <powei@google.com>
2025-12-12 14:15:58 -08:00
Filament Bot
c300f77151 [automated] Updating /docs due to commit f701c1e
Full commit hash is f701c1e1b5

DOCS_ALLOW_DIRECT_EDITS
2025-12-12 22:00:55 +00:00
Mathias Agopian
16734fc767 EMSCRIPTEN always supports fences, even at feature level 0 (#9507)
FIXES=[467783405]
2025-12-12 13:59:51 -08:00
Nemi
f701c1e1b5 Implement KHR_materials_dispersion (#9471)
This change adds support for the KHR_materials_dispersion glTF extension, which introduces a dispersion property for refractive materials.

The dispersion property controls the angular separation of colors transmitting through a refractive object, allowing for more realistic rendering of materials like glass and diamonds.

  Changes include:
   - Added a dispersion property to the material definition.
   - Updated the shaders to incorporate the dispersion effect in the refraction calculations.
   - Added a new test case for dispersion.
   - Updated the material documentation to include the new dispersion property.
2025-12-12 13:55:25 -08:00
Mathias Agopian
98cec207ce don't trigger an assert failure when getFenceStatus fails (#9511)
this is not an error that should warrant an assertion, since it's
possible for fences to not be supported at all.

FIXES=[467782111]

Co-authored-by: Powei Feng <powei@google.com>
2025-12-12 13:38:55 -08:00
Powei Feng
3ecdf71917 test: use backend NOOP for material tests 2025-12-12 13:04:17 -08:00
Powei Feng
ebba65e558 test: disable tests that tries to have a real backend 2025-12-12 12:40:06 -08:00
Powei Feng
177d23b3ac test: remove test_material_parser from CI
Seems to actually be initializing an engine

Failed with

reason: /Users/runner/work/filament/filament/filament/backend/src/opengl/platforms/PlatformCocoaGL.mm:177: failed assertion 'success == kCVReturnSuccess'
2025-12-12 12:19:39 -08:00
Powei Feng
cfd402f424 test: fix broken filament test again 2025-12-12 12:01:40 -08:00
Powei Feng
b7e492d674 test: fix missing dep filamat in test 2025-12-12 11:34:31 -08:00
Powei Feng
d7e0202f37 github: fix race condition for windows build (#9513)
A. Move filament_test_material.cpp to be part of test_filament
    (This won't be triggered during the windows build)
 B. Add chaining dependencies in third_party/draco/tnt so that
    there is no race in writing/reading generate.stamp

-------------
Failures
-------------
A.

C:\a\filament\filament\out\cmake-mtd\filament\test\resources\filament_test_resources.c(1,1): error C1083: Cannot open source file: 'C:\a\filament\filament\out\cmake-mtd\filament\test\resources\filament_test_resources.c': Permission denied [C:\a\filament\filament\out\cmake-mtd\filament\test\test_material_parser.vcxproj]

B.

CUSTOMBUILD : CMake error : Cannot restore timestamp "C:/a/filament/filament/out/cmake-mtd/third_party/draco/tnt/CMakeFiles/generate.stamp": Access is denied. [C:\a\filament\filament\out\cmake-mtd\third_party\draco\tnt\draco_compression_bit_coders.vcxproj]
2025-12-12 19:16:09 +00:00
Doris Wu
4227d04eb7 Add label for PlotLines calls (#9506)
Co-authored-by: Powei Feng <powei@google.com>
2025-12-12 16:32:41 +08:00
Powei Feng
272ed14737 github: fix brew dependency failure (#9512)
The failure is included below.  The reason for the failure is
because we caches ~/Library/Caches/Homebrew, but this might
present a mismatch with the latests homebrew.

We bump the cache version.

------------------------------------
failure
------------------------------------
Error: missing keywords: :date, :because
/opt/homebrew/Library/Homebrew/formula.rb:4631:in 'deprecate!'
/opt/homebrew/Library/Homebrew/formulary.rb:290:in 'block in Formulary.load_formula_from_json!'
/opt/homebrew/Library/Homebrew/formulary.rb:228:in 'Class#initialize'
/opt/homebrew/Library/Homebrew/formulary.rb:228:in 'Class#new'
/opt/homebrew/Library/Homebrew/formulary.rb:228:in 'Formulary.load_formula_from_json!'
/opt/homebrew/Library/Homebrew/formulary.rb:959:in 'Formulary::FromAPILoader#load_from_api'
/opt/homebrew/Library/Homebrew/formulary.rb:943:in 'Formulary::FromAPILoader#klass'
/opt/homebrew/Library/Homebrew/formulary.rb:524:in 'Formulary::FormulaLoader#get_formula'
/opt/homebrew/Library/Homebrew/formulary.rb:1045:in 'Formulary.factory'
/opt/homebrew/Library/Homebrew/formula.rb:2447:in 'Formula.[]'
/opt/homebrew/Library/Homebrew/formula.rb:671:in 'block in Formula#versioned_formulae'
/opt/homebrew/Library/Homebrew/formula.rb:670:in 'Array#each'
/opt/homebrew/Library/Homebrew/formula.rb:670:in 'Enumerable#filter_map'
/opt/homebrew/Library/Homebrew/formula.rb:670:in 'Formula#versioned_formulae'
/opt/homebrew/Library/Homebrew/unlink.rb:9:in 'Homebrew::Unlink.unlink_versioned_formulae'
/opt/homebrew/Library/Homebrew/formula_installer.rb:1166:in 'FormulaInstaller#link'
/opt/homebrew/Library/Homebrew/formula_installer.rb:955:in 'FormulaInstaller#finish'
/opt/homebrew/Library/Homebrew/formula_installer.rb:905:in 'FormulaInstaller#install_dependency'
/opt/homebrew/Library/Homebrew/formula_installer.rb:816:in 'block in FormulaInstaller#install_dependencies'
/opt/homebrew/Library/Homebrew/formula_installer.rb:816:in 'Array#each'
/opt/homebrew/Library/Homebrew/formula_installer.rb:816:in 'FormulaInstaller#install_dependencies'
/opt/homebrew/Library/Homebrew/formula_installer.rb:569:in 'FormulaInstaller#install'
/opt/homebrew/Library/Homebrew/install.rb:493:in 'Homebrew::Install.install_formula'
/opt/homebrew/Library/Homebrew/install.rb:420:in 'block in Homebrew::Install.install_formulae'
/opt/homebrew/Library/Homebrew/install.rb:417:in 'Array#each'
/opt/homebrew/Library/Homebrew/install.rb:417:in 'Homebrew::Install.install_formulae'
/opt/homebrew/Library/Homebrew/cmd/install.rb:396:in 'Homebrew::Cmd::InstallCmd#run'
/opt/homebrew/Library/Homebrew/brew.rb:101:in '<main>'
2025-12-12 01:26:06 +00:00
Powei Feng
223a754200 Revert "[automated] Updating /docs due to commit 32fcc1a"
This reverts commit 27c268f865.
2025-12-11 17:09:26 -08:00
Powei Feng
af480a58c4 Reapply "build: improve build.sh for Android with documentation (#9500)"
This reverts commit 192738ecb9.
2025-12-11 17:09:20 -08:00
Powei Feng
192738ecb9 Revert "build: improve build.sh for Android with documentation (#9500)"
This reverts commit 32fcc1a81b.
2025-12-11 16:55:49 -08:00
Filament Bot
27c268f865 [automated] Updating /docs due to commit 32fcc1a
Full commit hash is 32fcc1a81b

DOCS_ALLOW_DIRECT_EDITS
2025-12-12 00:52:05 +00:00
Powei Feng
32fcc1a81b build: improve build.sh for Android with documentation (#9500)
- Fix Android build in build.sh so that the tools dir are
   properly set to corresponding folders for debug vs. release.
 - Update/consolidate documentation to explain the Android Studio
   workflow better.
 - Move documentation from outdated apps folder to BUILDING.md
2025-12-12 00:46:00 +00:00
Powei Feng
621eca340e matdbg/matinfo: add column labels for output (#9502)
- Identify the columns that are being printed out when using
   matinfo to print out a material
- Add constant of blank space offset
2025-12-11 23:56:16 +00:00
Powei Feng
ee6c8c3e76 vk: unconditionally enable systrace for group markers (#9501) 2025-12-11 09:09:38 -08:00
Powei Feng
dcf7621c35 Revert "[automated] Updating /docs due to commit d4efef9"
This reverts commit 6a8193ea80.
2025-12-10 12:16:51 -08:00
Filament Bot
6a8193ea80 [automated] Updating /docs due to commit d4efef9
Full commit hash is d4efef9a9b

DOCS_ALLOW_DIRECT_EDITS
2025-12-10 19:12:21 +00:00
Benjamin Doherty
4e37a445cf Merge branch 'rc/1.68.1' into release 2025-12-10 11:05:05 -08:00
Benjamin Doherty
474a4f3fcd Bump version to 1.68.2 2025-12-10 11:05:05 -08:00
Benjamin Doherty
d4efef9a9b Release Filament 1.68.1 2025-12-10 11:04:56 -08:00
yein
cdffc9eaa0 Allow embedding material source in cmat (#9484)
* Allow embedding material source in cmat
* Compress material string
2025-12-10 10:31:51 -08:00
Sungun Park
a162a65dce Add JobQueue (#9480)
JobQueue is a thread-safe producer-consumer queue, which will be used
for asynchronous operations.
2025-12-10 18:00:58 +00:00
Ben Doherty
369bab4744 Implement setPresentationTime for Metal (#9470) 2025-12-09 14:54:06 -08:00
Benjamin Doherty
98d4874a3a Add missing VulkanDriver.h header 2025-12-09 14:26:07 -08:00
Powei Feng
c98038b2d7 vk: remove precondition for createStreamNative (#9497)
Keep it's original behavior of no-op
2025-12-09 13:48:38 -08:00
yrcloud
849c4bb8c5 webgpu: manage a pool of staging buffers for updateGPUBuffer (#9486)
- only MapAsync the staging buffers that are not being used by any command anymore (the commands have finished executing on GPU)
- additionally, in WebGPUQueueManager, create a blank new submission state when a new command encoder is generated instead of in submit()

BUGS=450620535
2025-12-09 12:20:03 -05:00
Mathias Agopian
ee64322d76 improve the memcpy benchmark (#9490)
- remove the multi-threaded tests, they added too much noise
- added a memset test
- make sure we allocate the buffer aligned to 16KB
2025-12-08 21:23:51 -08:00
Mathias Agopian
79d65a768a Fix(FrameInfo): fix typos and endFrame logic (#9499)
When the frame history's circular queue is full and the oldest
frame is not yet ready to be processed, we must skip the current
frame.

This change ensures that if `beginFrame` is skipped, the
corresponding `endFrame` is also skipped. This prevents data
corruption in the frame history.
2025-12-09 01:17:42 +00:00
Doris Wu
37610dc8f3 Unify zstd dependency for basisu (#9493) 2025-12-09 01:00:38 +00:00
Mathias Agopian
2e31dc20e4 Fix(FrameInfo): Improve robustness of frame info history management (#9496)
Address potential issues in FrameInfoImpl and FrameInfoManager:
 - Modify FrameInfoManager::beginFrame to handle cases where the 
   circular queue is full and the oldest frame is not yet ready, 
   logging a warning and skipping the frame. 
   This prevents potential use-after-free or data corruption by 
   ensuring only ready frames are removed from the history.

FIXES=[466081317]
2025-12-08 15:28:58 -08:00
Mathias Agopian
c67ed7a1d7 fix use-after-free of the EGL swapchain (#9495)
PlatformEGLAndroid holds onto the current swapchain in order to use
it when beginFrame is called. Usually the swapchain is set just before
beginFrame is called. However, that's not the case for standalone
views. These are independent of the swapchain and doing "swapchain
stuff" for them is nonsensical.

So make sure that:

1. PlatfromEGLAndroid doesn't hold onto a dangling pointer when the 
   swapchain is destroyed. And add proper null checks.
2. Don't do the "swapchain stuff" when beginFrame is called in the
   context of a standalone view.
   We now reserve frameID 0 for that purpose (meaning the frameid is
   non sensical for these).

We're currently relying on frameID to not wrap-around. At 120 fps, 
that's about 1 year. This will be addressed in a later PR.

FIXES=[462827028, 461399487]
2025-12-08 15:14:03 -08:00
Mathias Agopian
ae3d98fb47 fix use-after-free of the EGL swapchain (#9495)
PlatformEGLAndroid holds onto the current swapchain in order to use
it when beginFrame is called. Usually the swapchain is set just before
beginFrame is called. However, that's not the case for standalone
views. These are independent of the swapchain and doing "swapchain
stuff" for them is nonsensical.

So make sure that:

1. PlatfromEGLAndroid doesn't hold onto a dangling pointer when the 
   swapchain is destroyed. And add proper null checks.
2. Don't do the "swapchain stuff" when beginFrame is called in the
   context of a standalone view.
   We now reserve frameID 0 for that purpose (meaning the frameid is
   non sensical for these).

We're currently relying on frameID to not wrap-around. At 120 fps, 
that's about 1 year. This will be addressed in a later PR.

FIXES=[462827028, 461399487]
2025-12-08 14:54:34 -08:00
rafadevai
a938a790fa VK: Do memcpy if the uniform buffer is WRITE_SHARED (#9491)
With UBO batching, the frontend guarantees that
doing a memcpy to the buffer if safe.
2025-12-08 17:52:53 +00:00
dependabot[bot]
71d556dddf Bump urllib3 in /docs_src/build in the pip group across 1 directory (#9494)
Bumps the pip group with 1 update in the /docs_src/build directory: [urllib3](https://github.com/urllib3/urllib3).


Updates `urllib3` from 2.5.0 to 2.6.0
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.5.0...2.6.0)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.6.0
  dependency-type: direct:production
  dependency-group: pip
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Powei Feng <powei@google.com>
2025-12-08 17:35:27 +00:00
Powei Feng
d61227b2fd material: remove checked-in .filamat for transform name test (#9487)
filament_test_material should not need to depend on a "fixed"
(or checked in) material.

Now the dependent .filamat is generated as needed as is
packaged with the checked-in test_material.filamat as before.
2025-12-07 00:39:41 +00:00
dependabot[bot]
612a6b00e4 Bump urllib3 in /test/renderdiff/src in the pip group across 1 directory (#9492)
Bumps the pip group with 1 update in the /test/renderdiff/src directory: [urllib3](https://github.com/urllib3/urllib3).


Updates `urllib3` from 2.5.0 to 2.6.0
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.5.0...2.6.0)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.6.0
  dependency-type: direct:production
  dependency-group: pip
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-06 16:21:41 -08:00
Ben Doherty
b3353b518c Metal: ensure framebuffer fetch is only used on macOS 11.0+ (#9481) 2025-12-05 13:39:52 -08:00
Patrick Ribas
0b44761d43 Allow PlatformEGLHeadless to load GLES (#9488) 2025-12-05 13:37:51 -08:00
yein
c7979e4023 update test materials to 68 (#9485) 2025-12-05 12:20:48 -08:00
Mathias Agopian
e00904e100 Update NDK version to 29 (latest) (#9489)
also 
- update the android build script to pull the version from 
  build/common/versions

- remove the ability to specify your own ndk version (this was
  undocumented and not fully implemented)

The NDK version now needs to appear in two place (unfortunately):
1. build/common/versions
2. build/android/build.sh
2025-12-05 11:29:02 -08:00
Sungun Park
96e2366569 Add config option for asynchronous mode (#9462) 2025-12-05 02:48:22 +00:00
Powei Feng
e9a3399d44 Revert "Add flag to guard camera near/far assertion (#9472)"
This reverts commit 3a92cdab3a.
2025-12-04 13:45:30 -08:00
Mathias Agopian
e76624862d don't use the -mcpu compiler flag (#9483)
`-mcpu` is intended to target a specific CPU instruction set and
optimization. That's not what we want to do here. What we want is
target an architecture, specifically armv8-a. So we use `-march` 
instead.  On 64 bits builds, we tune for cortex-a78, which is the
df the Pixel7 era. This doesn't mater much, but might give a little
boost on newer CPU cores. The idea here is that we care "less" about
older CPUs.
2025-12-04 11:29:19 -08:00
Powei Feng
c5c83a61d3 vk: fix spurious VK_ERROR_OUT_OF_DATE_KHR on swapchain resize (#9482)
Fixes #9476
Fixes #8604
2025-12-04 19:24:29 +00:00
Powei Feng
ccf0d6205f Fix a couple of CI errors (#9477)
- Make sure that renderdiff fails when either building or
   rendering fails (the previous problem was in the use of &&
   that masked the non-zero exit).
 - Make sure that golden branch is properly parsed in
   postsubmit.yml
 - Disable vk loader debug by default
2025-12-04 18:40:05 +00:00
Powei Feng
f482c1d702 Fix texture leak in ImGuiHelper on shutdown (#9479) 2025-12-03 14:48:56 -08:00
Vignan Jitta
a4c056e822 Fix Wayland window data invalidation in NativeWindowHelperLinux (#9461) 2025-12-03 19:27:07 +00:00
Evan Mezeske
f5071b2aae Set the minimum required Metal version (#9425) 2025-12-03 19:10:00 +00:00
Sungun Park
0fa13ee43d Fix race condition with garbage collection (#9465)
This change fixes an intermittent crash caused by a thread race
condition.

The crash happened when a CallbackHandler::Callback (triggered by
engine.flush()) attempted to create an instance of a Structure of Arrays
(SoA) like TransformManager, which adds items to SoA) at the same time
that the garbage collection job (FEngine::gc, which removes items from
SoA) was running.

This conflict is resolved by modifying the logic to ensure that the
garbage collection task completes synchronously before the callback
operations begin.
2025-12-03 16:14:39 +00:00
Doris Wu
1d2b8a08fa Refactor the API usage for UBO batching (#9443) 2025-12-03 21:54:30 +08:00
rafadevai
0c06744450 Cleanup code related to stream transform matrix (#9464)
Clean up all the code related to setting a transform
matrix for a stream.
2025-12-03 00:47:56 -08:00
Powei Feng
4ada29fbc3 Revert "Add flag to guard camera near/far assertion (#9472)"
This reverts commit 3a92cdab3a.
2025-12-02 20:58:12 -08:00
Filament Bot
76182231dd [automated] Updating /docs due to commit 8cd6915
Full commit hash is 8cd6915b9d

DOCS_ALLOW_DIRECT_EDITS
2025-12-03 00:20:02 +00:00
Powei Feng
1a9fb54897 Merge branch 'rc/1.68.0' into release 2025-12-02 16:17:33 -08:00
Powei Feng
515637b3a5 Bump version to 1.68.1 2025-12-02 16:17:33 -08:00
Powei Feng
8cd6915b9d Release Filament 1.68.0 2025-12-02 16:17:24 -08:00
Powei Feng
3e0bb70146 Update ImGui to 1.92.5 (#9463) 2025-12-02 15:54:37 -08:00
imadr
e09c702e74 Fix build on windows when vulkan is not supported (#9439)
Co-authored-by: Sungun Park <sungunpark@google.com>
2025-12-02 15:54:30 -08:00
Mathias Agopian
f90de26bc2 fix disable_gpu_frame_complete_metric flag (#9473)
- set the flag to true (metrics disabled) until downstream is ready
- make sure to exit the JobQueue thread before destroying it

BUGS=[464370498]
2025-12-02 15:02:52 -08:00
Powei Feng
cc2e661aab Update ImGui to 1.92.5 (#9463) 2025-12-02 22:42:35 +00:00
Powei Feng
3a92cdab3a Add flag to guard camera near/far assertion (#9472)
BUGS=465516676
2025-12-02 22:22:38 +00:00
Powei Feng
b367982c23 platform: fix PlatformEGLAndroid include (#9469)
Only need AndroidNdk (already included) and not AndroidNativeWindow
2025-12-02 21:46:48 +00:00
Sungun Park
a4f4dc617e Support null initialization for Invocable (#9466)
This allows for code like:

Invocable<void()> inv = []() { /*do something*/ };
inv = nullptr;
2025-12-02 21:29:14 +00:00
dependabot[bot]
2eb0f11d05 Bump werkzeug (#9467)
Bumps the pip group with 1 update in the /test/renderdiff/src directory: [werkzeug](https://github.com/pallets/werkzeug).


Updates `werkzeug` from 3.1.3 to 3.1.4
- [Release notes](https://github.com/pallets/werkzeug/releases)
- [Changelog](https://github.com/pallets/werkzeug/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/werkzeug/compare/3.1.3...3.1.4)

---
updated-dependencies:
- dependency-name: werkzeug
  dependency-version: 3.1.4
  dependency-type: direct:production
  dependency-group: pip
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-02 18:39:19 +00:00
Ben Doherty
e8670da782 Fix getter methods (#9450) 2025-12-02 10:30:49 -08:00
Doris Wu
6694df991c Use vector instead of unordered_set in FenceManager (#9458) 2025-12-02 13:44:27 +08:00
imadr
8b2bfa7e9d Fix build on windows when vulkan is not supported (#9439)
Co-authored-by: Sungun Park <sungunpark@google.com>
2025-12-02 02:22:38 +00:00
Serge Metral
7386220325 Stream API Vulkan Backend (#9164)
* Adding the begin frame message for later xtrace post processing.

* First commit

* This is not needed

* Bypass the AHB* issue.

* Typo: Forgot to remove the function.

* Typo: No const specifier.

* Removing the const.

* no exception

* Feedback from discussions with Powei.

* Making the changes discussed with the team.

* Removing useless comments.

* Adding the required methods for allocation.

* Forgot one more switch case.

* Moving the resource to –fvkmemory::Resource type.

* Adding streamed set.

* Allocating every frame for streamed textures.

* Changing the binding logic.

* Proper checks for the streamed texture.

* Cleanup.

* Chaning the logic of the state tracking for streamed textures.

* Fixed full screen bug.

* Refactoring of the code.

* Typo.

* GitHub feedback.

* Github feedback

* feedback.

* Typo

* Feedback.

* Feedback.

* Feedback

* Feedback

* Feedback

* Fixing the Android path.

* Fixing the Android path.

* Feedback.

* feedback

* Feedback.

* Nit

* Feedback

* Feedback

* Feedback

* vk: fix update after bind (wrt descriptor set) validation error

In filament, once a descriptor set is bound, we no longer make updates
to it. However, this guarrantee was broken in the external sampler/image
because a colorspace change might necessitate a layout change, and
thereby a new descriptor needs to be generated with the appropriate
externally sampled image updated in the new set.

Another use case is the Stream API, where each frame we might be
getting a different AHardwareBuffer, meaning we need to update one
or multiple sampler bindings in a set that might have been bound in
a previous frame.

In this change, we always create a new set when there's a change
in the image currently bound to an existing set (while accounting for
whether we need to use a new externally sampled layout or not).

* Removing the decision on whether to use external format or not out of the streamed texture manager. The issue is that all textures are external, not all are using external format. But it's more robust to let the external format image manager rely on the AHB* to decide if the format is external or not. Regardless (because the memory is external) we need to send this to the external image manager.

* Fixing the validation layer in the Stream CL.

* Typo and comment clarification.

---------

Co-authored-by: Powei Feng <powei@google.com>
2025-12-01 11:13:47 -08:00
Sungun Park
000faeaca7 Fix bindVAO for OpenGL (#9453)
Currently bindVertexArray call generates an object for the default VAO,
which is not originally intended.
2025-12-01 18:55:02 +00:00
Mathias Agopian
88a1c13dfb don't assume compositor and frame timing are always available (#9449)
- this is not true fro headless swapchains
- and potentially some timings might not be available on a given nativewindow

Previously the code would handle these errors gracefully, but the 
errors were still generated. Now, we query the availability and only
make the calls  if supported.

Also on EGL, we don't attempt to use private APIs -- this code path
should never be used anyways.
2025-12-01 10:39:35 -08:00
Powei Feng
193d5b48b6 Bump MATERIAL_VERSION to 68 2025-12-01 10:29:33 -08:00
Powei Feng
3f9783ac02 Bump MATERIAL_VERSION to 68 2025-12-01 10:28:23 -08:00
rafadevai
4e6dc67ae8 VK: Disable depth testing in some cases (#9455)
Depth testing come with a cost, so when the depth
test is marked to always pass and writting to depth
buffer is disable, just disable the feature.

This will also match the GL backend behavior.
2025-12-01 09:40:26 -08:00
Doris Wu
666140bb73 Fix ios x86 build (#9459) 2025-12-01 09:04:09 -08:00
Doris Wu
56050de5cd metal: implement memory mapping (#9454) 2025-11-27 11:05:07 +08:00
Mathias Agopian
772136decd fix a typo/bad merge that broke setPresentationTime (#9452)
FIXES=[462533574]
2025-11-21 11:40:17 -08:00
Mathias Agopian
68142039f2 fix a typo/bad merge that broke setPresentationTime
FIXES=[462533574]
2025-11-21 11:39:38 -08:00
Powei Feng
f664601c51 android: add readPixels callback for ModelViewer (#9440) 2025-11-21 19:33:36 +00:00
Ben Doherty
f06b27b7fb Fix getter methods (#9450) 2025-11-21 00:37:28 +00:00
Mathias Agopian
ef53ce88d4 don't assume compositor and frame timing are always available (#9449)
- this is not true fro headless swapchains
- and potentially some timings might not be available on a given nativewindow

Previously the code would handle these errors gracefully, but the 
errors were still generated. Now, we query the availability and only
make the calls  if supported.

Also on EGL, we don't attempt to use private APIs -- this code path
should never be used anyways.
2025-11-20 15:32:02 -08:00
Mathias Agopian
07c8b0a9a7 frameId must be monotonic in the SwapChain (#9447)
The frameId coming from a Renderer must be monotonic when seen from
a SwapChain (Specifically a ANativeWindow on Android), if it's not
the case, we must clear that part of the history.

This can happen if a SwapChain is used with two different Renderer; at
this point that SwapChain's history is no longer connected to that
Renderer.
2025-11-20 13:26:04 -08:00
Mathias Agopian
ef18030e1a frameId must be monotonic in the SwapChain (#9447)
The frameId coming from a Renderer must be monotonic when seen from
a SwapChain (Specifically a ANativeWindow on Android), if it's not
the case, we must clear that part of the history.

This can happen if a SwapChain is used with two different Renderer; at
this point that SwapChain's history is no longer connected to that
Renderer.
2025-11-20 13:23:58 -08:00
Sungun Park
060564e8d2 Bump version to 1.68.0 2025-11-19 11:30:29 -08:00
Sungun Park
b89a05a378 Merge branch 'rc/1.67.1' into release 2025-11-19 11:30:28 -08:00
Powei Feng
1e4029532f vk: fix leaking swapchains again (#9410)
- Adjust order of destroy call in both headless and platform
   swapchains.  We need to be careful of the order due to
   assumptions made by the base class's destroy().
 - remove `=0` since VulkanPlatformSwapChainBase::destroy() has
   an implementation.

Fixes #9403
2025-11-17 17:04:10 -08:00
Mathias Agopian
be7149918d AndroidNativeWindow must also work on 32-bits architectures (#9424) 2025-11-10 14:54:09 -08:00
Mathias Agopian
f95a58ad72 Fix a race condition when tearing down FrameInfo (#9413)
* HandleAllocator::deallocate() was unsafe

It needs to know the concrete type to call the proper destructor, so
if it was given a base type handle (e.g. Handle<HwFoo>) it would not
destroy it properly.

* add AsyncJobQueue::cancelAll()

* Fix a race condition when tearing down FrameInfo

It is actually invalid to destroy a Handle<HwFence> while inside
fenceWait().

Updated the HwFence implementations so that they don't pretend they can
handle being destroyed during fenceWait(), they can't.

FrameInfo now cancels all the pending callbacks and waits for the 
currently executing one to terminate, *before* destroying the
handles.

Reenable the gpuFrameComplete metric, as it should be working now.
2025-11-10 14:52:32 -08:00
Mathias Agopian
5a9b56a1b7 Properly use SDK 26+ APIs (#9417)
With minSDK less than 26, it's unsafe to use APIs in nativewindow.h 
that appeared at API 26 or more, even when using the weak symbol
technique. This is because pre 26, libnativewindow.h didn't exist and
therefore the build system cannot link against it.

Currently Filament's minSdk is 21, which means we should never use
nativewindow.h API after 26.

In this PR we chose the strategy at compile time; either the more
modern weak symbol or the old way with dlsym based on __ANDROID_API__.
2025-11-07 10:28:16 -08:00
Powei Feng
8310896232 vk: fix thread-safety wrt queryFrameTimestamps() (#9415)
queryFrameTimestamps() and queryCompositorTiming() are both
synchronous APIs, but VuklanSwapchain is not a thread-safe
ref-counted handle (i.e. fvkmemory::ThreadSafeResource). We move
the Platform::SwapChain* pointers to a thread-safe map that is
mapped by the handle id.
2025-11-07 10:05:11 -08:00
Benjamin Doherty
cc66f7c230 Add missing mutex header 2025-11-05 15:35:16 -08:00
Mathias Agopian
5695a5b43d add a feature flag for FrameInfo::gpuFrameComplete (#9409)
There are several race conditions caused by this feature. So we add
this flag and disable it by default, for now.
2025-11-05 15:33:30 -08:00
Benjamin Doherty
3cd2f0c386 Bump MATERIAL_VERSION to 67 2025-11-05 10:35:03 -08:00
Benjamin Doherty
7f717f8f92 Merge branch 'rc/1.67.0' into release 2025-11-05 10:33:25 -08:00
Benjamin Doherty
93437c33f8 Bump version to 1.67.1 2025-11-05 10:33:25 -08:00
Benjamin Doherty
85d0543eb1 Add workaround for invalid handle assertion 2025-11-05 10:32:03 -08:00
Anish Goyal
b03180650c Check for null fences to avoid segfault in tests (#9389)
* Check for null fences to avoid segfault in tests

In some test environments, creating a sync or fence backed by an Android
fence returns null. In order to avoid NPEs, cover this scenario with a
null check.

* Address PR - add log statement

Log that native fences are not supported when unable to create a native
sync fence.
2025-11-04 12:56:25 -05:00
Benjamin Doherty
d9fd0823ae Add missing mutex header 2025-11-03 18:28:25 -05:00
Benjamin Doherty
d1c331529e Bump MATERIAL_VERSION to 67 2025-11-03 16:03:30 -05:00
Mathias Agopian
8b97948149 vkWaitForFences() must be called with the read-lock held 2025-11-03 12:08:27 -08:00
Mathias Agopian
6e3da09ec2 fix a possible deadlock on exit (#9377)
The deadlock happened because FrameInfoManager needs to wait that all
fences have signaled before it can be destroyed.

The fix here is simply to destroy the fence without waiting (for safety
we do wait after we destroy them).

This uncovered another problem where all backends didn't handle this
correctly.

We now explicitly handle this when destroying a fence: we make sure it
unblocks all the waiters and returns an error.

FIXES=[457243841]
2025-11-03 13:27:40 -05:00
Mathias Agopian
a27cb66257 fix transparent picking (#9390)
FIXES=[456489383]
2025-11-03 13:22:24 -05:00
Mathias Agopian
230a5d8a93 Fix GLES2 UBO emulation (#9392)
The binding cache didn't take into account the UBO offset.

FIXES=[456802974]
2025-11-03 13:22:18 -05:00
Ben Doherty
66186ba396 Metal: support MSAA SwapChain flag (#9361) 2025-11-03 13:22:11 -05:00
Ben Doherty
40a66263ed Refactor Metal command buffer error logging (#9383) 2025-11-03 13:22:05 -05:00
Powei Feng
56c8d3eb49 Merge branch 'rc/1.66.2' into release 2025-10-29 11:09:39 -07:00
Powei Feng
65200838b9 Bump version to 1.67.0 2025-10-29 11:09:39 -07:00
Sungun Park
7d7906b836 Bump version to 1.66.2 2025-10-21 12:56:42 -07:00
Sungun Park
64656cf602 Merge branch 'rc/1.66.1' into release 2025-10-21 12:56:41 -07:00
Benjamin Doherty
1f039b917a Bump version to 1.66.1 2025-10-14 14:25:29 -07:00
Benjamin Doherty
2f2b4dc0fa Merge branch 'rc/1.66.0' into release 2025-10-14 14:25:28 -07:00
Ben Doherty
07144e833b Fix, revert to C++17 string_view constructor (#9315) 2025-10-13 15:00:24 -07:00
Ben Doherty
c3be134e1a Fix, Abseil compilation error with StaticString (#9314) 2025-10-13 13:36:49 -07:00
Benjamin Doherty
1536c61d2a Bump MATERIAL_VERSION to 66 2025-10-13 11:47:33 -07:00
Jordan Rupprecht
c56db04ec7 Add missing #include <ios> (#9305)
This is needed to instantiate `std::streampos`. It currently relies on transitive header inclusion to get that, which is going away for libc++ in ebcf1bf2ec.
2025-10-09 11:05:19 -07:00
Powei Feng
8c445264fd Bump version to 1.66.0 2025-10-07 15:54:24 -07:00
Powei Feng
2a86c0c60e Merge branch 'rc/1.65.4' into release 2025-10-07 15:54:23 -07:00
Powei Feng
e1bb4dcce6 Revert "Make matc workarounds default to NONE again" (#9295)
This reverts commit d11a6b4467.

Breakage detailed in following bug

BUGS=449740720
2025-10-07 15:52:16 -07:00
Powei Feng
713769bbde Add missing optional include for MaterialParser (#9296) 2025-10-07 15:52:07 -07:00
Sungun Park
29e7bc3e21 Bump version to 1.65.4 2025-09-30 18:50:52 +00:00
Sungun Park
c903903fcb Merge branch 'rc/1.65.3' into release 2025-09-30 18:50:51 +00:00
Mathias Agopian
89edb1a129 Fix matdbg build 2025-09-29 10:43:09 -07:00
Sungun Park
9eb6b17325 Fix a crash for MaterialCache
The parser object was accessed to generate a key after being passed to
the lambda using std::move(). This led to a crash on certain platforms
(at least on Windows).

This change fixes it by creating key first before moving the parser
object into the lambda.
2025-09-29 09:09:16 -07:00
Powei Feng
75a1498a95 Bump version to 1.65.3 2025-09-24 11:53:24 -07:00
Powei Feng
0cb9e85c66 Merge branch 'rc/1.65.2' into release 2025-09-24 11:53:23 -07:00
Powei Feng
72abf1fc7d vk: guard export fence creation 2025-09-22 12:57:21 -07:00
Ben Doherty
87cfa6a0de Metal: log command buffer errors (#9224) 2025-09-22 12:16:45 -07:00
Sungun Park
d183347120 Merge branch 'rc/1.65.1' into release 2025-09-19 15:42:36 +00:00
Sungun Park
9916f9ec63 Bump version to 1.65.2 2025-09-19 15:42:36 +00:00
Mathias Agopian
4a65fa75fc Fix descriptor set update bug
the buffer offset in descriptors wasn't updated if it was the only 
value to change when setting the descriptor.


FIXES=[443991507]
2025-09-16 10:14:35 -07:00
Sungun Park
5d8e366649 Update MATERIAL_VERSION to 64 2025-09-16 10:07:59 -07:00
Ben Doherty
ba769212e9 Fix g3 build (#9209) 2025-09-11 13:28:29 -07:00
Benjamin Doherty
035d75873d Bump version to 1.65.1 2025-09-09 17:15:52 -07:00
Benjamin Doherty
ce71136c8f Merge branch 'rc/1.65.0' into release 2025-09-09 17:15:51 -07:00
Benjamin Doherty
15c54e8e67 Revert "Update all per-object/instance buffers all at once"
This reverts commit 9f3c0ec8ef.
2025-09-08 17:50:17 -04:00
Benjamin Doherty
2101444f46 Bump MATERIAL_VERSION to 65 2025-09-08 10:19:08 -04:00
Sungun Park
2bb9d13797 Improve getEyeFromViewMatrix() (#9184)
Make the size of PerViewUib 2KiB again.

Add overloading functions for getEyeFromViewMatrix() and
getClipFromWorldMatrix().

BUGS=[441127971]
2025-09-04 12:02:22 -07:00
Sungun Park
edbaa30ad8 Add getEyeFromViewMatrix() for vertex shader (#9175)
This new method, intended for the vertex shader, returns a matrix that
transforms vertices from view space (also known as head space) to the
current eye space.

BUGS=[441127971]
2025-09-03 18:03:15 -07:00
Powei Feng
04cac2159f Bump version to 1.65.0 2025-09-02 11:17:53 -07:00
Powei Feng
426c2e01ed Merge branch 'rc/1.64.1' into release 2025-09-02 11:17:52 -07:00
Sungun Park
320162bb19 fix: Make ZstdHelper compatible with UBSan (#9152)
In ZstdHelper::isCompressed call, `src` may not be aligned to 4 bytes,
which is violating the alignment requirement of
`UndefinedBehaviorSanitizer: misaligned-pointer-use`, thereby resuling
in a runtime failure with UBSan enabled. So reconstruct the 32-bit
integer as a workaround.
2025-08-29 16:07:18 -07:00
rafadevai
1043eaa076 GL: Fix memory leak for external texture with non external sampler (#9159)
In EGLAndroid, external textures imported from an AHB
that dont use a SAMPLER_EXTERNAL are not properly destroyed,
causing a memory leak that eventually leads to an OOM.
2025-08-29 16:07:01 -07:00
Powei Feng
6a28bdb3fc vk: fix rendertarget uninitialized fields (#9153) 2025-08-27 13:43:04 -07:00
Sungun Park
b440217503 Disable amortized shader compile by default
This is a temporary resolution until we fix an underlying issue.
2025-08-27 13:37:23 -07:00
Sungun Park
b3ddad7070 Bump version to 1.64.1 2025-08-21 12:04:34 -07:00
Sungun Park
2274bfddb2 Merge branch 'rc/1.64.0' into release 2025-08-21 12:01:48 -07:00
Powei Feng
46ccb6bab1 Feature flag guard GEN_MIPMAPPABLE precondition (#9134) 2025-08-21 12:00:45 -07:00
Mathias Agopian
70680721c4 correctly handle UTF8 strings in materials 2025-08-21 10:16:02 -07:00
Mathias Agopian
aeb292f5e1 Unit test for LineDictionary and fix subtle bugs
- add conveniences function to make LineDictionary look like a vector
- a pattern must start on a word boundary but "_" wasn't treated as one
- getIndices() must return the empty vector when any of the substring
  is not found
2025-08-21 10:15:39 -07:00
Sungun Park
74c68fe312 Merge branch 'rc/1.64.0' into release 2025-08-19 21:51:07 +00:00
Sungun Park
0865e3d042 Update MATERIAL_VERSION to 64 2025-08-18 09:46:08 -07:00
Benjamin Doherty
43432ddc39 Bump version to 1.64.0 2025-08-13 11:47:24 -04:00
Benjamin Doherty
80ef2ed67e Merge branch 'rc/1.63.1' into release 2025-08-13 11:47:22 -04:00
Ben Doherty
93ad78a81d matp: Fix crash when reflecting parameters (#9089) 2025-08-13 11:46:10 -04:00
Ben Doherty
94b8ee481f Fix: webgpu error regarding mismatched pipeline (#9056) 2025-08-11 17:30:28 -04:00
Ben Doherty
05bd56d0e8 matp: Remove accidental switch fallthrough (#9082) 2025-08-11 17:27:28 -04:00
Powei Feng
11d3d82f13 Fix two compilation errors (#9041)
- Include <limits> in bitset.h
- The type could not be inferred for Scene.cpp's `SharedState`
  line.  The failure came from clang version 1:14.0-55~exp2
2025-08-07 16:01:26 -07:00
Powei Feng
c368d977ea Bump version to 1.63.1 2025-08-05 22:59:47 -07:00
Powei Feng
f384f504b8 Merge branch 'rc/1.63.0' into release 2025-08-05 22:59:46 -07:00
Powei Feng
f3f65e8dbb Feature flag guard compat check of material instance and desc-set (#9035)
This will allow clients more time to correct their code.
2025-08-05 16:43:02 -07:00
Powei Feng
ac29bb5094 utils: add precond/postcond macro guarded by feature flags
We link the behavior of certain precondition/postcondition checks to feature flag states.

- If provided *flag* is true, then this macro will assert when the *condition* is false.
- If provided *flag* is fase, then this macro will output a warning when the condition is false.
- If the condition is true, then neither of the above will happen

These two macros will enable us to provide less restrictive behavior for certain correctness assertions, allowing clients to modify their before enabling these assertions by default.
2025-08-05 16:42:55 -07:00
Powei Feng
4909826d21 Update MATERIAL_VERSION to 63 2025-08-03 22:57:04 -07:00
Powei Feng
4e920ed077 vk: fix broken iblprefilter path (#9019)
The issue is that we need to reset the bound info in
VulkanDescriptorSetCache when the current command buffer completes
recording.
2025-07-31 10:51:51 -07:00
Benjamin Doherty
db6baed3a5 Bump version to 1.63.0 2025-07-31 10:27:35 -07:00
Benjamin Doherty
ede471ce0b Merge branch 'rc/1.62.2' into release 2025-07-31 10:27:34 -07:00
Sungun Park
580157662d Bump version to 1.62.2 2025-07-14 23:11:32 +00:00
Sungun Park
c7ad86906c Merge branch 'rc/1.62.1' into release 2025-07-14 23:11:31 +00:00
Sungun Park
a488b3d3ee Add #include <cstdlib> to avoid compilation error (#8922) 2025-07-14 18:27:41 +00:00
Powei Feng
1014c7b214 Add feature flag for attribute stride check (#8913)
We also add a define to log (instead of assert) failtures of
certain correctness checks.  This allows clients to gradually
fix their code.
2025-07-14 11:19:54 -07:00
Sungun Park
005e9a6812 gl: Enhance error reporting for asynchronous shader operations (#8938)
* gl: Enhance error reporting for asynchronous shader operations

When ShaderCompilerService asynchronously compiles and links shaders,
unexpected errors (e.g., GL_CONTEXT_LOST) can occur after the initial GL
call, complicating diagnostics.

This change improves error context by collecting the GL error status
when querying shader compilation and program link statuses. This
provides a more detailed understanding of error origins.

BUGS=[373396840]

* feedback
2025-07-10 17:07:16 +00:00
Powei Feng
1a08514d9f Bump version to 1.62.1 2025-06-30 16:39:25 -07:00
Powei Feng
3f5965e591 Merge branch 'rc/1.62.0' into release 2025-06-30 16:39:24 -07:00
Powei Feng
cb9944979e Bump Material Version to 62 2025-06-29 22:36:53 -07:00
Benjamin Doherty
3ffea1a984 Bump version to 1.62.0 2025-06-25 12:29:32 -07:00
Benjamin Doherty
0f5351b184 Merge branch 'rc/1.61.2' into release 2025-06-25 12:29:31 -07:00
Ben Doherty
6ca16574d9 Fix ASAN use-after-stack-free in VulkanPlatform (#8897) 2025-06-25 12:28:44 -07:00
Sungun Park
4cd76247e2 Bump MATERIAL_VERSION to 61 2025-06-13 15:39:31 -07:00
Sungun Park
c4fb50f0a4 Bump version to 1.61.2 2025-06-13 15:23:06 -07:00
Sungun Park
c6d447d963 Revert "materials: introduce mutable spec constants (#8795)"
This reverts commit 8a1a0b0fd2.
2025-06-13 15:11:25 -07:00
Sungun Park
2c03004311 Fix: Prevent deadlock when loading programs from cache (#8849)
When a program was created directly from a cached blob in
`ShaderCompilerService`, its associated token was not signaled as ready
in the THREAD_POOL mode. This oversight caused a deadlock at the
`token->wait()` call during program destruction.

This commit resolves the issue by skipping the token's readiness check
upon destruction if the program was created from the cache blob.

BUGS=[423221474]
2025-06-12 14:37:03 -07:00
Benjamin Doherty
0b409e90f0 Temporary workaround for PlatformMetal 2025-06-12 13:24:23 -07:00
Sungun Park
2fda451f6b Bump version to 1.62.0 2025-06-12 00:31:49 +00:00
Sungun Park
505969cdf6 Merge branch 'rc/1.61.1' into release 2025-06-12 00:31:48 +00:00
Sungun Park
0acda5fc2d Bump MATERIAL_VERSION to 61 2025-06-12 00:30:48 +00:00
Sungun Park
dffa7a29a4 Fix: Submit callback handle on completion (#8818)
This reverts a behavioral regression introduced in commit c3542b135e,
which deferred callback submission until the program was first used.

This commit restores the correct behavior by submitting the callback
handle as soon as the token's work is complete. This occurs either upon
successful `gl.program` population or via cancellation, ensuring the
caller is properly notified that the resource loading operation has
concluded.
2025-06-04 10:10:09 -07:00
Powei Feng
e0529a9ba4 github: update windows runner due to 2019 being "stuck" (#8814) 2025-06-03 13:36:27 -07:00
Powei Feng
1362c09512 github: update windows runner due to 2019 being "stuck" (#8814) 2025-06-03 13:36:08 -07:00
Powei Feng
3105a67e15 Bump version to 1.61.1 2025-06-03 12:02:20 -07:00
Powei Feng
fc287bd7c0 Merge branch 'rc/1.61.0' into release 2025-06-03 12:02:20 -07:00
Powei Feng
3c09e36410 Add missing include in JobSystem.cpp (#8812) 2025-06-03 11:45:56 -07:00
Powei Feng
3a6d36cd66 utils: add additional guards for Tracing (#8810)
The addition JobSystem.cpp allows for defining
FILAMENT_TRACING_ENABLED across targets.

Addingin FILAMENT_TRACING_ENABLED to the #if in Tracing.h prevents
perfetto from being included.
2025-06-03 11:29:10 -07:00
Powei Feng
70b5e11653 Flip conditional for fixing missing samplers (#8811) 2025-06-03 11:29:01 -07:00
Powei Feng
10ea71c476 Fix always bind uniform logic in MaterialInstance (#8801)
The logic for duplicating UBO was omitted after #8739
2025-06-02 10:54:57 -07:00
Powei Feng
72ad5da352 gl: keep external texture id in sync (#8803)
(Attributed to @dsternfeld7)
2025-06-02 10:39:50 -07:00
Mathias Agopian
e10cfd7da9 attempt to fix external streams with protected context
There was several issues:

1) when we're switching contexts (e.g. between protect and regular) we
   needed up reattach all SurfaceView (i.e. streams), because they need
   to be attached on currently active context.

2) reattaching, because it's implemented as detach + attach, would 
   destroy the current gl texture id and create a new one. However,
   because of the way descriptor-sets were implemented, that GL
   texture id was kept inside the descriptor, later leading to using
   a destroyed texture id.
   The fix here is to store texture handles in descriptors, so that
   we can update the id independently. 

3) we also needed to invalidate all bound descriptor sets because it's
   now possible for descriptor sets to have outdated descriptors
2025-05-30 16:49:31 -07:00
Powei Feng
a6caf8e630 Fix leaking dummy depth array texture (#8796) 2025-05-30 10:29:42 -07:00
Mathias Agopian
6ad63bb8c8 fix a buffer overflow during init
the default cubemap has RGBA pixels (4 bytes per pixel).
2025-05-29 14:40:02 -07:00
Benjamin Doherty
38744e8297 Temporary workaround for PlatformMetal 2025-05-28 23:16:47 -07:00
Mathias Agopian
fe197c4628 fix a use after free of texture data during init (#8786) 2025-05-28 22:40:31 -07:00
Powei Feng
20b940a70f Add option to disable GTAO (#8785) 2025-05-28 15:36:12 -07:00
Powei Feng
a1cf965787 vk: add missing header (#8781) 2025-05-28 15:31:21 -07:00
Sungun Park
58e59977db Fix broken android samples (#8784)
that use DescriptorType::SAMPLER_EXTERNAL.
2025-05-28 15:31:13 -07:00
Sungun Park
c5842d2f44 Fix a compile error
This is a fix for the compile error caused by
86a500c846
2025-05-23 10:34:04 -07:00
Benjamin Doherty
758c957f42 Bump MATERIAL_VERSION to 61 2025-05-20 12:46:06 -07:00
Benjamin Doherty
b036428fdc Bump version to 1.61.0 2025-05-20 12:42:41 -07:00
Benjamin Doherty
f483c93c5a Merge branch 'rc/1.60.1' into release 2025-05-20 12:42:40 -07:00
Benjamin Doherty
12faf3a01f Add missing header 2025-05-19 14:10:15 -07:00
Sungun Park
29ececc5f9 Bump version to 1.60.1 2025-05-13 21:27:39 +00:00
Sungun Park
4d35a7db75 Merge branch 'rc/1.60.0' into release 2025-05-13 21:27:38 +00:00
Powei Feng
eb8260ab2c Update release note after cherry-pick 2025-05-13 13:45:26 -07:00
David Neto
596c17ecc0 Move calls to SPV remapper to another .cpp file (#8729) 2025-05-13 13:42:48 -07:00
Sungun Park
4536752c47 Revert "Add getter functions for settings to build ColorGrading object (#8699)"
This reverts commit f10d226565.
2025-05-13 11:12:24 -07:00
Sungun Park
3b9f4df1a8 Update MATERIAL_VERSION to 60 2025-05-12 16:43:29 +00:00
Benjamin Doherty
c701a19292 Temporary workaround for PlatformMetal 2025-05-12 16:39:24 +00:00
Powei Feng
b68e2a9503 Bump version to 1.60.0 2025-05-08 09:06:55 -07:00
Powei Feng
99fbb63528 Merge branch 'rc/1.59.5' into release 2025-05-08 09:06:54 -07:00
Benjamin Doherty
10169b94a2 Temporary workaround for PlatformMetal 2025-05-06 14:05:39 -07:00
Powei Feng
7c0f62ce9d Revert "Use the Perfetto SDK instead of ATRACE" (#8701)
This reverts commit ca3ff7e08e.
2025-05-06 11:02:37 -07:00
Benjamin Doherty
10fdb3b9a2 Merge branch 'rc/1.59.4' into release 2025-05-01 17:33:48 -07:00
Benjamin Doherty
0236f45bad Bump version to 1.59.5 2025-05-01 17:33:48 -07:00
Sungun Park
123bce928c Bump version to 1.59.4 2025-04-21 22:05:40 +00:00
Sungun Park
963fc9b15a Merge branch 'rc/1.59.3' into release 2025-04-21 22:05:39 +00:00
Benjamin Doherty
99c82115d4 Temporary workaround for PlatformMetal 2025-04-21 16:54:40 +00:00
Powei Feng
219208049b Bump version to 1.59.3 2025-04-16 15:47:34 -07:00
Powei Feng
c4f0798c5d Merge branch 'rc/1.59.2' into release 2025-04-16 15:47:33 -07:00
Benjamin Doherty
fac324d5cf Temporary workaround for PlatformMetal 2025-04-14 10:07:36 -07:00
Benjamin Doherty
97ed8143e4 Bump version to 1.59.2 2025-04-09 10:21:09 -07:00
Benjamin Doherty
43860b6830 Merge branch 'rc/1.59.1' into release 2025-04-09 10:21:04 -07:00
Sungun Park
c0884c03dc Merge branch 'rc/1.59.0' into release 2025-03-31 22:23:27 +00:00
Sungun Park
c24e5089c4 Bump version to 1.59.1 2025-03-31 22:23:27 +00:00
Powei Feng
4be96c8748 Update MATERIAL_VERSION to 59 2025-03-28 15:39:58 -07:00
Powei Feng
a1397c9ce9 Bump version to 1.59.0 2025-03-28 15:34:20 -07:00
Powei Feng
fd6facf52f Merge branch 'rc/1.58.2' into release 2025-03-28 15:34:19 -07:00
Powei Feng
2919298fed Update MaterialVersion to 58 2025-03-26 10:57:32 -07:00
Powei Feng
b0bc351642 engine: Add 1D LUT feature flag (#8568)
Note that the flag is default to false while we roll out this
feature.
2025-03-25 16:14:45 -07:00
Powei Feng
9758e68424 Fix test breaking changes with workarounds (#8569)
- Some tests require textures larger than 2048. Change the minimum
  to 4096 for now, and file proper bugs for tests.
- The introduction of uint8_t to DescriptorSetLayoutBinding
  caused unintended padding with using this struct as a hash key.
  We comment out the relevent code for now.
2025-03-25 16:14:34 -07:00
Benjamin Doherty
b5ad54b963 Temporary workaround for PlatformMetal 2025-03-24 16:27:16 -07:00
Doris Wu
57f6214637 Some cleanups (#8558)
* Clean up includes

* Fix the logic
2025-03-24 09:19:37 -07:00
Doris Wu
26171e7f76 Remove trailing whitespace (#8556) 2025-03-24 09:19:31 -07:00
Benjamin Doherty
472054631a Bump version to 1.58.2 2025-03-19 16:17:23 -07:00
Benjamin Doherty
a3609eba2e Merge branch 'rc/1.58.1' into release 2025-03-19 16:17:22 -07:00
Benjamin Doherty
d53abebbe9 Bump MATERIAL_VERSION to 58 2025-03-17 08:58:24 -07:00
Sungun Park
cec7150b4c Bump version to 1.58.1 2025-03-10 22:12:21 +00:00
Sungun Park
dee94b56db Merge branch 'rc/1.58.0' into release 2025-03-10 22:12:20 +00:00
Powei Feng
046d90be1c Update HandleAllocator in test (#8508) 2025-03-10 13:06:16 -07:00
Sungun Park
7fda028191 Bump MATERIAL_VERSION to 58 2025-03-10 17:49:17 +00:00
Sungun Park
00445918ff Bump version to 1.58.0 2025-03-10 17:47:08 +00:00
Ajmal Kunnummal
f32ae2c900 Add a way to pass a transform matrix along with Stream::setAcquiredImage (#8496)
BUGS=[399959254]
---------

Co-authored-by: Syed Idris Shah <idrisshah@google.com>
Co-authored-by: Haneul Kim <haneulk730@gmail.com>
Co-authored-by: Powei Feng <powei@google.com>
Co-authored-by: Doris Wu <doriswu@google.com>
Co-authored-by: Mathias Agopian <mathias@google.com>
2025-03-10 17:37:15 +00:00
Ajmal Kunnummal
0be7fa77a6 Update the associated uniforms every frame for materials with attached Streams (#8493)
BUGS=[399959254]
2025-03-10 17:36:25 +00:00
Ajmal Kunnummal
2765269e46 Add a way to specify an additional uniform name along with a sampler param for the associated transform matrix (#8490)
BUGS=[399959254]
2025-03-10 17:35:57 +00:00
Ajmal Kunnummal
4a45db21b4 Add a way to query the transform matrix of a surface texture from the driver (#8489)
* Add a way to query the transform matrix of a surface texture from the driver

BUGS=[399959254]
2025-03-10 17:35:32 +00:00
Powei Feng
49ad01fa64 Bump version to 1.57.3 2025-03-05 14:37:48 -08:00
Powei Feng
be0b7373e9 Merge branch 'rc/1.57.2' into release 2025-03-05 14:37:42 -08:00
Benjamin Doherty
d6338fd927 Temporary workaround for PlatformMetal 2025-03-04 23:25:05 +00:00
Benjamin Doherty
6a1e3c54ec Fix: Metal crashing when a render pass is abandoned 2025-03-04 11:31:38 -08:00
Benjamin Doherty
60132845ed Bump version to 1.57.2 2025-02-27 10:09:03 -08:00
Benjamin Doherty
e96a302e79 Merge branch 'rc/1.57.1' into release 2025-02-27 10:09:02 -08:00
Mathias Agopian
a4dd357781 Initialize mShadowCulling properly (#8476)
Just like mCulling, mShadowCulling needs to be inherited from the 
material.


Fix breakage introduced in #8422 with attempted fix in #8475 and
caused by an uninitialized variable (mShadowCulling).

BUGS=[391679058]
2025-02-27 10:08:08 -08:00
Ben Doherty
009fb0e121 Make setCullingMode also set shadow culling (#8475) 2025-02-27 10:08:04 -08:00
Powei Feng
2779c00ec4 Add workaround for handle tag issue (#8467)
BUGS=397766275
2025-02-21 13:57:33 -08:00
Powei Feng
43d6909939 gl: fix missing external texture target 2025-02-18 09:59:15 -08:00
Powei Feng
4eb669d59a gl: fix missing external texture target 2025-02-12 12:25:02 -08:00
Sungun Park
3681fe9657 Merge branch 'rc/1.57.0' into release 2025-02-10 23:33:25 +00:00
Sungun Park
1dcc141e26 Bump version to 1.57.1 2025-02-10 23:33:25 +00:00
Sungun Park
d8b994bef1 Move OpenGLDriverBase.h under src/opengl/ (#8433) 2025-02-10 15:21:58 -08:00
Benjamin Doherty
e057844742 Bump MATERIAL_VERSION to 57 2025-02-10 09:49:35 -08:00
Benjamin Doherty
6aa20312e5 Temporary workaround for PlatformMetal 2025-02-10 09:49:06 -08:00
Powei Feng
082da86ca8 Merge branch 'rc/1.56.8' into release 2025-02-06 11:14:08 -08:00
Powei Feng
dd51e1dd96 Bump version to 1.57.0 2025-02-06 11:14:08 -08:00
Mathias Agopian
b204b92e35 make sure FXAA resets alpha channel when it's the last postfx (#8412)
If FXAA is the last post process effect (i.e. no upscaling), and
color grading produced a luma channel, then FXAA needs to reset the
alpha channel to 1.
2025-02-04 11:53:15 -08:00
Powei Feng
0a5b85f740 Add feature flag for material/instance destroy assert (#8411)
This will allow a more lenient rollout of the assertion, which
otherwise will increase crashes for current clients.

We also disable features.engine.debug.assert_material_instance_in_use
by default (it was enabled for debug builds).
2025-02-04 11:34:35 -08:00
Powei Feng
01318588d5 java: must use return var in Engine (#8409) 2025-02-03 23:45:57 -08:00
Mathias Agopian
71b193a192 fix color grading as subpass
This broke in 48a2c64. Fixes #8401.
2025-02-03 15:09:39 -08:00
Ben Doherty
07324d63b6 Metal: add config to abandon frame if drawable cannot be acquired (#8397) 2025-01-31 13:32:42 -08:00
Benjamin Doherty
3387f5bf33 Bump version to 1.56.8 2025-01-29 16:41:21 -08:00
Benjamin Doherty
18d7cf980b Merge branch 'rc/1.56.7' into release 2025-01-29 16:41:19 -08:00
Mathias Agopian
031981a72c Fix ShadowMapManager ShadowMap alignment (#8398) 2025-01-29 11:56:32 -08:00
Mathias Agopian
a495d90110 mistakenly enabled the Shadow Atlas feature 2025-01-27 22:16:09 -08:00
Benjamin Doherty
9686b3e294 Bump version to 1.56.7 2025-01-16 13:00:04 -08:00
Benjamin Doherty
69a327c7e7 Merge branch 'rc/1.56.6' into release 2025-01-16 13:00:03 -08:00
Sungun Park
d5bcc31c71 Merge branch 'rc/1.56.5' into release 2025-01-08 21:59:23 +00:00
Sungun Park
95894f9634 Bump version to 1.56.6 2025-01-08 21:59:23 +00:00
Powei Feng
4695e93633 Merge branch 'rc/1.56.4' into release 2024-12-17 16:39:38 -08:00
Powei Feng
b332bf376f Bump version to 1.56.5 2024-12-17 16:39:38 -08:00
Powei Feng
aaac6e7662 renderdiff: allow for explicit (compile-time) linking of osmesa (#8301)
If the shared osmesa lib is not found, then we assume that the
library has been compile-time linked via the linker.  This is to
accommodate build frameworks where compile-time linking is
preferred.
2024-12-12 10:56:29 -08:00
Sungun Park
8ef8b345ae Merge branch 'rc/1.56.3' into release 2024-12-11 02:17:56 +00:00
Sungun Park
2cc375e4cc Bump version to 1.56.4 2024-12-11 02:17:56 +00:00
Mathias Agopian
592c91f20e pre-populate the default material's depth variants
This restores the old behavior with depth variant caching. We pay the
price at engine init time, instead of when the variant is needed the
first time. We can revisit this later.

Note that the default material doesn't have all possible depth variants
(e.g. VSM), but that pre-caches the most popular ones.

BUGS=[381946222]
2024-12-09 18:18:19 +00:00
Powei Feng
04b62960de Merge branch 'rc/1.56.2' into release 2024-11-25 15:46:04 -08:00
Powei Feng
e2492dfde8 Bump version to 1.56.3 2024-11-25 15:46:04 -08:00
Sungun Park
60ce48e327 Merge branch 'rc/1.56.1' into release 2024-11-19 17:20:17 +00:00
Sungun Park
7588189874 Bump version to 1.56.2 2024-11-19 17:20:17 +00:00
Sungun Park
b6a69fba18 Update missing version bumps from last update 2024-11-19 17:19:22 +00:00
Sungun Park
a3bfad95ab Bump material version to 56 (#8281)
Fix the material version correctly.
2024-11-18 16:08:06 -08:00
Mathias Agopian
cf7360bf8b fix uninitialized variable on ES2 devices
On ES2 devices (or in forceES2 mode), we emulate the sRGB swapchain
in the shader if the h/w doesn't support it. In that case, the emulation
is controlled by a uniform that technically lives in the frameUniforms
block. However, the frameUniforms buffer is not updated, instead,
the uniform is manually set. Unfortunately, the UBO emulation
overrides it with the uninitialized variable.

BUGS=[377913730]
2024-11-13 13:54:00 -08:00
Ben Doherty
2a9dcd7c40 Metal: unbind descriptor sets upon destruction (#8268) 2024-11-13 12:21:44 -08:00
Powei Feng
e726964b85 vk: fix uninitialized param (#8253) 2024-11-06 14:34:38 -08:00
Benjamin Doherty
003e500571 Merge branch 'rc/1.56.0' into release 2024-11-04 15:21:18 -08:00
Benjamin Doherty
72ae60fa64 Bump MATERIAL_VERSION to 56 2024-11-04 09:41:41 -08:00
Benjamin Doherty
06106b7a00 Bump version to 1.56.0 2024-11-04 09:34:10 -08:00
Benjamin Doherty
c7319ac559 Merge branch 'rc/1.55.1' into release 2024-11-04 09:34:09 -08:00
Powei Feng
66abb75bc4 vk: remove incorrect assert 2024-10-28 15:54:09 -07:00
Ben Doherty
e4b1f0413b Fix potential crash when a descriptor set is destroyed but not unbound (#8215) 2024-10-20 22:39:27 -07:00
Ben Doherty
9e1ee2f290 Fix potential crash when a descriptor set is destroyed but not unbound (#8215) 2024-10-18 16:42:52 -04:00
Powei Feng
1d0c23a3f7 Initialize bool in DescriptorSet.h (#8173)
This class has a ( = default) constructor and hence should have
explicit initialization in its definition.
2024-10-14 06:15:21 +00:00
Mathias Agopian
b8f43e4bc8 fix shadow multiplier mode
when shadow multiplier was used, the material used the wrong
variant (unlit).
2024-10-14 06:14:35 +00:00
Powei Feng
22bb67e0b0 Bump version to 1.55.1 2024-10-14 06:07:43 +00:00
Mathias Agopian
9bd994e6a4 workaround Mesa glDeleteBuffers() bug
Mesa always clears the generic binding if the buffer deleted
is bound to an indexed binding, even if it's not bound to the
generic binding.

BUGS=[371324321]
2024-10-04 15:27:37 -07:00
Ben Doherty
c3c9fe1b06 Fix OpenGL ES 2.0 descriptor set crash (#8176) 2024-10-04 15:27:30 -07:00
Powei Feng
e9e7911506 Fix imported texture path (#8175)
We need to also account for external image textures that are
imported in texture creation.
2024-10-04 15:27:10 -07:00
Powei Feng
0689e79441 Work around client descriptor set issues (#8171)
- We change GLDescriptorSet::Buffer default constructor to
  workaround a client's compiler set up issue.
- We removed the assert_invariant that checks that ubo/samplers
  are not changed after committed in DescriptorSet. This caused
  an existing client's build to crash.
2024-10-02 06:39:47 -07:00
Powei Feng
40a6510710 Merge branch 'rc/1.55.0' into release 2024-10-01 17:09:16 +00:00
Powei Feng
d6b1efd5e4 Change std::memcpy to memcpy in SkinningBuffer (#8169) 2024-10-01 16:58:02 +00:00
Powei Feng
6d0ab5a593 Add Descriptor Sets to Filament (#8165)
We add the concept of the descriptor set as a way to describe
shader resources into Filament. This is a comprehensive change
across Filament.

Info on descriptor sets is available here:
https://docs.vulkan.org/spec/latest/chapters/descriptorsets.html

Co-authored-by: Benjamin Doherty <bendoherty@google.com>
Co-authored-by: Mathias Agopian <mathias@google.com>
Co-authored-by: Sungun Park <sungunpark@google.com>
2024-09-27 23:22:29 -07:00
Benjamin Doherty
b2153e0ef6 Bump version to 1.55.0 2024-09-27 15:12:23 -07:00
Benjamin Doherty
0e4d35b9fd Merge branch 'rc/1.54.5' into release 2024-09-24 12:34:32 -07:00
Powei Feng
6cc4ae0ee8 vk: workaround a renderStandaloneView issue
Found through testing that renderStandaloneView+vk+swiftshader
seems to cause synchronization issues, which results in incorrect
rendering. Here we workaround the issue by forcibly flush and
wait per renderStandaloneView call.

BUG=361822355
2024-09-18 08:34:37 -07:00
Powei Feng
01711f47d9 Bump version to 1.54.5 2024-09-17 15:25:06 -07:00
Powei Feng
65aed719d7 Merge branch 'rc/1.54.4' into release 2024-09-17 15:25:05 -07:00
Powei Feng
3e556588fc Merge branch 'rc/1.54.3' into release 2024-09-10 12:26:56 -07:00
Powei Feng
429fd7acc6 Bump version to 1.54.4 2024-09-10 12:26:56 -07:00
Powei Feng
32b0625f36 Revert "reenable the SimplificationPass in spirv-opt"
This reverts commit 30387af61c.

Causes breakage on Pixel 8pro for 1P apps.
2024-09-09 10:37:11 -07:00
Sungun Park
bb1d1c7349 Merge branch 'rc/1.54.2' into release 2024-09-04 18:55:59 +00:00
Sungun Park
c967fb7860 Bump version to 1.54.3 2024-09-04 18:55:59 +00:00
Powei Feng
422fcea2cf Make builderMakeName public
This call is used in the BuilderNameMixin template definition,
which is a public API.
2024-09-04 17:07:51 +00:00
Mathias Agopian
b0d3f14243 a handle with a tag would sometime return "no tag"
this is because the key used to retrieve the tag was not "truncated"
like it was when inserting the tag in the hash-map.
2024-09-03 17:13:59 +00:00
Powei Feng
f5f1e56123 Re-enable DebugRegistry::setProperty for release build (#8086)
`DebugRegistry::setProperty` is no longer just applicable to debug
builds.

This change was previously added in 6c0bd36 but then reverted
in a7317e7. We re-enable it and separate it from the shadow
changes in this commit.
2024-08-28 12:17:11 -07:00
Sungun Park
bce91c56dd Merge branch 'rc/1.54.1' into release 2024-08-27 23:30:37 +00:00
Sungun Park
f743bedef9 Bump version to 1.54.2 2024-08-27 23:30:37 +00:00
Sungun Park
eb12e06387 Revert two depth relevant changes (#8083)
This reverts commits
- b70aa43727 "depth clamp cannot work with VSM"
- 6c0bd360b3 "Add support for depth clamp and use it for shadows"
2024-08-27 00:27:32 +00:00
Ben Doherty
40ce15cfbd Support tagging driver handles with a name (#8038) 2024-08-24 09:19:02 -07:00
Powei Feng
aa5f36e1e3 Bump version to 1.54.1 2024-08-20 08:55:19 -07:00
Powei Feng
c1a3450d9c Merge branch 'rc/1.54.0' into release 2024-08-20 08:55:18 -07:00
Powei Feng
4396a1a776 Fix misnumbered version in RELEASE_NOTES 2024-08-13 16:30:07 -07:00
Powei Feng
d88ab8d527 Bump version to 1.54.0 2024-08-13 16:22:56 -07:00
Powei Feng
a109a52f3d Merge branch 'rc/1.53.5' into release 2024-08-13 15:59:20 -07:00
Benjamin Doherty
a7b4b9d3a6 Merge branch 'rc/1.53.4' into release 2024-08-08 12:12:36 -07:00
Benjamin Doherty
e253051867 Bump version to 1.53.5 2024-08-08 12:12:36 -07:00
Benjamin Doherty
44d082049c Revert: inject the missing packing/unpacking function in ESSL 3.0 2024-08-06 15:11:25 -07:00
Benjamin Doherty
239b43e34d Add type_traits header 2024-08-05 10:59:14 -07:00
Sungun Park
1888c97245 Merge branch 'rc/1.53.3' into release 2024-07-31 16:23:06 +00:00
Sungun Park
c43c58af5d Bump version to 1.53.4 2024-07-31 16:23:06 +00:00
Sungun Park
6b43762dc7 Fix a crash for IBL resource loading (#8001)
This fixes a crash introduced by a8ace2891d

The refactored FrameInfoManager can cause a crash when IBL resource loading
happens because now the getLastFrameInfo() references an invalid value via the
`front` method. Return the default FrameInfo to resolve this.

Also fix a null pointer reference bug for OpenGLTimer::State, which
happenes when the renderer for IBLPrefilterContext is destroyed.
2024-07-29 15:31:59 -07:00
Sungun Park
c3f1a4c94d Merge branch 'rc/1.53.2' into release 2024-07-23 01:24:09 +00:00
Sungun Park
1fef82a826 Bump version to 1.53.3 2024-07-23 01:24:09 +00:00
Mathias Agopian
bef004e1b0 switch to new morphing API
- remove deprecated morphing APIs
- repair gltfio, samples and tests

The new API doesn't allow a MorphTargetBuffer per RenderPrimitive,
instead the MorphTargetBuffer is specified per Renderable.

gltfio separates RenderPrimitives from Renderables, in particular all
RenderPrimitives are created before their Renderable; this was
problematic for this change because all primitives must share
a single MorphTargetBuffer living in the Renderable.

To fix this, we're no longer initializing the morphing paramters
at RenderPrimitive creation, instead we store a reference to the
BufferSlot in the Primtive structure, so that later, when the Renderable
is created we can finally retrieve the BufferSlot and initialize its
morphing paramters, which are not available. The "morphing parameters"
are now expanded to contain the MorphTargetBuffer as before (except now
it's always the same for all the primitives of a Rendrable), as well
as the offset within the buffer and the vertex count.
2024-07-22 11:31:03 -06:00
Ben Doherty
936d0a7b1d Update imgui to v1.90.9 (#7977) 2024-07-18 16:41:31 -07:00
Mathias Agopian
2b651d4946 shader compilation could fail on ES 3.0 devices
the failure could happen if the shader didn't have any #extension
strings, which was likely to happen on release builds (e.g. on 
emulator).
2024-07-01 11:31:30 -07:00
Ben Doherty
d6ab9f1c0b Update cgltf to 1.14 (#7945) 2024-07-01 10:57:37 -07:00
Ben Doherty
786b7ec7ae Fix MetalBumpAllocator (#7951) 2024-06-28 13:09:39 -07:00
Benjamin Doherty
55173efc2c Bump version to 1.53.2 2024-06-25 11:46:54 -07:00
Benjamin Doherty
7fc8e339e7 Merge branch 'rc/1.53.1' into release 2024-06-25 11:46:53 -07:00
Ryan
0395df3689 Fix use-after-free of a std::mutex in PresentCallable. (#7934)
If a user is using `setFrameScheduledCallback()`, managing the provided PresentCallable during engine shutdown is tricky -- we'll likely get a final frame scheduled when we flush the engine's work queue, but the PresentCallable will schedule the final CAMetalDrawable to be released on main thread afterwards, even if we call `present(false)` to skip it. If the swap chain is destroyed before that main queue block gets executed, the mutex presenting that drawable will no longer exist, causing a crash.

To make things easier, store the std::mutex in a shared_ptr, so that a PresentCallable can safely outlive the FSwapChain instance that created it and clean itself up afterwards.

Alternatives considered, all of which seem unfortunate:
* Require users to clear out the callback before shutting down the engine, so that any final drawables are immediately discarded instead of using PresentCallable
* Require users to split up the engine teardown across two main queue blocks, ensuring that the PresentCallable cleanup executes before swapchains are destroyed
* Drop the PresentCallable on the ground and leak the memory
2024-06-24 11:01:44 -07:00
Benjamin Doherty
64f03b3832 Merge branch 'rc/1.53.0' into release 2024-06-17 17:26:55 -07:00
Benjamin Doherty
982b159b3e Bump version to 1.53.1 2024-06-17 17:26:55 -07:00
Benjamin Doherty
bbd4177dd0 Merge branch 'rc/1.52.3' into release 2024-06-11 16:42:17 -07:00
Benjamin Doherty
6e3cccf30c Bump version to 1.53.0 2024-06-11 16:42:17 -07:00
Ryan
5d5f53e6e3 Acquire a mutex before releasing CAMetalDrawables on main thread. (#7888)
PresentDrawable was moved to main thread by default in google#7535 and stopped
most crashes when a drawable is released. But there still appears to be crashes
if a drawable is released on main thread at the same time that -nextDrawable is
called from the Filament render thread. (It's likely that the drawable pool in
CAMetalLayer is completely non-thread-safe.)

So, add a mutex to the swapchain and always acquire it before creating or
releasing a CAMetalDrawable.

Users can opt out of this behavior by passing
-DFILAMENT_LOCK_METAL_DRAWABLE_POOL=0.
2024-06-11 09:17:55 -07:00
Mathias Agopian
ec44c4a157 export PanicStream since it's a public API 2024-06-05 11:05:09 -07:00
Sungun Park
74751a0971 Merge branch 'rc/1.52.2' into release 2024-06-03 18:10:41 +00:00
Sungun Park
28069e43dc Bump version to 1.52.3 2024-06-03 18:10:41 +00:00
Powei Feng
3603202cc5 Merge branch 'rc/1.52.1' into release 2024-05-29 16:19:39 -07:00
Powei Feng
a8596ae9c9 Bump version to 1.52.2 2024-05-29 16:19:39 -07:00
Benjamin Doherty
3fb9521c10 Bump MATERIAL_VERSION to 52 2024-05-28 13:59:28 -07:00
Ryan
17f32d198a Throw an exception when failing to build a Metal render pipeline state. (#7878)
Currently, if this fails we log the error message to stderr (which
doesn't get captured by most crash reporting systems) and then crash in
a postcondition assert. By including the error message in an exception
reason and throwing an ObjC exception, we get better discoverability of
error causes.

(Building a render pipeline state from shaders is usually when a shader
actually gets JITted from LLVM IR to GPU-specific code, so if we
accidentally used a feature that's not available on the local GPU, we'll
find out about it here.)
2024-05-24 13:12:11 -07:00
Benjamin Doherty
11ecaa2fbf Revert "Metal: implement more accurate buffer tracking (#7839)"
This reverts commit 54a800a25d.
2024-05-24 13:11:43 -07:00
Benjamin Doherty
d56f769d4d Bump version to 1.52.1 2024-05-21 12:48:07 -07:00
Benjamin Doherty
a46ca78f41 Merge branch 'rc/1.52.0' into release 2024-05-21 12:48:06 -07:00
Mathias Agopian
7ba437b2c6 fix/remove wrong asserts 2024-05-17 14:06:09 -07:00
Benjamin Doherty
b4c33d2ab2 Bump MATERIAL_VERSION to 52 2024-05-17 14:00:42 -07:00
Benjamin Doherty
455025349d Rename release to 1.52.0 2024-05-16 14:32:51 -07:00
Mathias Agopian
3fa4aab02a change the morphing API so it uses only one buffer per renderable
The current API allowed to have a buffer for each primitive in a
renderable. We instead restrict the API so that there is a single 
MorphTargetBuffer for the whole renderable, shared by all primitives.
The buffer can be shared thanks to the "offset" parameter on
setMorphTargetBufferAt().

Also
- fix FMorphTargetBuffer::updateDataAt()
- add support for the "offset" parameter of setMorphTargetBufferAt()
2024-05-16 14:12:57 -07:00
Ben Doherty
5485ef238f Implement push constants for Metal (#7858) 2024-05-16 13:33:36 -07:00
Ben Doherty
a5541de84d Metal, fix callbacks being called only once (#7856) 2024-05-15 13:19:44 -07:00
Sungun Park
2d184f5077 Merge branch 'rc/1.51.8' into release 2024-05-13 20:53:51 +00:00
Sungun Park
c2e3a97705 Bump version to 1.51.9 2024-05-13 20:53:51 +00:00
Benjamin Doherty
0d22805342 Revert "Switch setFrameScheduledCallback to use utils::Invocable (#7792)"
This reverts commit e7feee7d5b.
2024-05-10 13:50:39 -07:00
Benjamin Doherty
aeb0c14ce1 Rename Metal log message 2024-05-10 11:25:51 -07:00
Ben Doherty
144d99df57 Metal: implement more accurate buffer tracking (#7839) 2024-05-10 11:15:28 -07:00
Ryan
268e204a9f ryanmyers: Improve logging for Metallib function lookup failures (#7836)
If a .metallib was compiled with a target iOS version that's newer than
the current device, loading the .metallib may succeed, but finding main0
(or any other function in it) will fail. Currently, this causes a crash
due to an assert. Logging the error and returning
MetalFunctionBundle::error() makes the crash slightly easier to
diagnose.

(Note that in practice, this will probably be a useless "Compiler
encountered an internal error" message -- the GPU backend is crashing,
and the Metal stub library sees XPC_ERROR_CONNECTION_INTERRUPTED. It
retries up to 3 times (crashing each time) and then gives up.)
2024-05-09 16:10:01 -07:00
Ben Doherty
a13aa728bf Metal: log slow buffer allocation times (#7834) 2024-05-08 14:44:03 -07:00
Benjamin Doherty
c0ee1e2874 Log excess buffer allocations for Metal 2024-05-07 15:40:32 -07:00
Powei Feng
1b9d2c6fa6 Bump version to 1.51.8 2024-05-07 14:35:57 -07:00
Powei Feng
7489c55532 Merge branch 'rc/1.51.7' into release 2024-05-07 14:35:56 -07:00
Ben Doherty
2d157e8fe1 Add preferredShaderLanguage option to Engine::Config (#7816) 2024-05-06 15:49:37 -07:00
Benjamin Doherty
3ba082da13 Metal: track types of buffers 2024-05-06 10:26:30 -07:00
Benjamin Doherty
7ae2773222 Log excess buffer allocations for Metal 2024-05-06 10:20:48 -07:00
Eliza Velasquez
b7eb12bd0c filagui: Split uiBlit material into two
Unfortunately, the external uniform was not optimized out as expected. The only
option is to split it into its own independent material.
2024-05-05 21:57:06 -07:00
Eliza Velasquez
305bfb36d8 Fix broken ImGui on web
I was unfortunately naive about the way that Filament handled external textures
on non-GLES platforms. This fix restricts the changes to Android (which is the
only place this change is required in the first place). Long story short, the
change broke WebGL. Desktop seems to be unaffected.
2024-05-05 21:56:56 -07:00
Benjamin Doherty
880b454702 Bump version to 1.51.7 2024-04-29 16:49:37 -07:00
Benjamin Doherty
996e2a206e Merge branch 'rc/1.51.6' into release 2024-04-29 16:49:36 -07:00
Ben Doherty
b57fbfb128 Add license information to matedit (#7790) 2024-04-29 10:20:21 -07:00
Ben Doherty
2f36df8d93 Add option to preserve text shaders (#7786) 2024-04-23 11:15:52 -06:00
Benjamin Doherty
76a8f18700 matedit: fix use-after-free 2024-04-23 11:15:20 -06:00
Sungun Park
53af1fd052 Merge branch 'rc/1.51.5' into release 2024-04-22 20:48:10 +00:00
Sungun Park
cb88e7555f Bump version to 1.51.6 2024-04-22 20:48:10 +00:00
Ben Doherty
35fa79ec23 Support backends with multiple shader languages and precompiled Metal libraries (#7769) 2024-04-21 20:00:22 -06:00
Ben Doherty
d9cba80bcf Introduce new matedit tool (#7759) 2024-04-19 16:35:45 -04:00
Mathias Agopian
ed4154ee0e fix a GL backend crash when shutting down
the gl backend did some of its cleanup in the its destructor,
including calling into OpenGL, however, the destructor is called from
the main thread, not the GL thread, so these calls would be no-ops at
best, and crashes in the worst case.
2024-04-18 14:09:34 -07:00
Powei Feng
65f2df7776 Merge branch 'rc/1.51.4' into release 2024-04-15 11:05:23 -07:00
Powei Feng
1b1c03814a Bump version to 1.51.5 2024-04-15 11:05:23 -07:00
Sungun Park
b89a0173ef Merge branch 'rc/1.51.3' into release 2024-04-08 20:49:28 +00:00
Sungun Park
1fec588fb1 Bump version to 1.51.4 2024-04-08 20:49:28 +00:00
Ben Doherty
de1edbdf25 Metal re-apply: throw an NSException when attempting to draw with invalid program (#7741) 2024-04-05 17:51:01 -07:00
Ben Doherty
d468303bc9 Export utils::panic function (#7740) 2024-04-05 17:50:56 -07:00
Benjamin Doherty
81658541a1 Bump version to 1.51.3 2024-04-01 16:44:40 -07:00
Benjamin Doherty
d0eb56ff20 Merge branch 'rc/1.51.2' into release 2024-04-01 16:44:39 -07:00
Powei Feng
85589a7d16 Merge branch 'rc/1.51.1' into release 2024-03-28 11:48:00 -07:00
Powei Feng
d476c7fa1b Bump version to 1.51.2 2024-03-28 11:48:00 -07:00
Powei Feng
3ed008c0b6 Bump material version to 51 in MaterialEnums.h 2024-03-26 21:38:02 +00:00
Powei Feng
66ec81187d vk: delete instead of ref-count EmptyTexture (#7711) 2024-03-26 20:36:45 +00:00
Powei Feng
0efd94a769 Add missing include to Platform.h (#7709) 2024-03-26 20:09:47 +00:00
Eliza Velasquez
1801def1ee Allow rendering thread to pause
This PR adds a new `pause()` option to the `Engine` `Builder` and a new function
`setPaused()` to the `Engine`. While paused, the rendering thread will pause
indefinitely for commands as if none are available. As soon as the rendering
thread is unpaused, the commands are immediately executed.
2024-03-25 22:46:06 +00:00
Powei Feng
61155644d5 gl: v1.51.1 local fix for merge mistake 2024-03-25 22:13:40 +00:00
Sungun Park
b3ec8b188e Add FILAMENT_ENABLE_MULTIVIEW option (#7707)
This allows the engine to include multiview shader code for default
materials.
2024-03-25 21:49:15 +00:00
Ben Doherty
dbf0cde330 Metal: track buffer allocations (#7556) 2024-03-22 12:48:24 -07:00
Mathias Agopian
072562c571 Add an option to disable use-after-free checks in the backend
BUGS=330403836
2024-03-22 11:36:43 -07:00
Mathias Agopian
780799f30b PlatformEGL::createSwapChain never returns a nullptr anymore
in case the swapchain creation fails, it will now return a swapchain
with an EGL_NO_SURFACE handle. this will avoid having to nullptr check
the pointer in various places and will revert to the previous behavior
on failure.

FIXES=[329659681]
2024-03-22 11:36:37 -07:00
Benjamin Doherty
cf0c1f74dc Bump version to 1.51.1 2024-03-17 13:12:41 -07:00
Benjamin Doherty
d3ca32efbe Merge branch 'rc/1.51.0' into release 2024-03-17 13:12:40 -07:00
Benjamin Doherty
de6df6dc0e Bump MATERIAL_VERSION to 51 2024-03-14 10:40:26 -07:00
Ben Doherty
6dd85c6530 Remove erroneous assertion (#7661) 2024-03-12 14:33:14 -07:00
Ben Doherty
5ca7f41513 Metal: respect disableParallelShaderCompile config (#7659) 2024-03-12 13:08:43 -07:00
Ben Doherty
4ad07e25d4 Move SwapChain flags into separate file (#7654) 2024-03-12 13:08:35 -07:00
Sungun Park
89a191c2e9 Merge branch 'rc/1.50.6' into release 2024-03-11 21:38:38 +00:00
Sungun Park
f63296fc18 Bump version to 1.51.0 2024-03-11 21:38:38 +00:00
Ben Doherty
ca27bb58bf Metal: change shader compilation pool size to 1 (#7639) 2024-03-08 10:33:37 -08:00
Powei Feng
86d2e11801 Try fixing windows artifact output again (#7637)
The [previous] change assumed that the shell is powershell, but the shell is actually commands (cmd). 

The [previous] change assumed we're in the root directory.  This assumption is probably correct [ref]. So we keep that change.

[ref]:  https://github.com/google/filament/blob/main/build/windows/build-github.bat#L134
[previous]: 373c5710b1
2024-03-07 10:51:06 -08:00
Powei Feng
cd528e57ab Merge branch 'rc/1.50.5' into release 2024-03-06 13:01:20 -08:00
Powei Feng
4a465450f1 Bump version to 1.50.6 2024-03-06 13:01:20 -08:00
Powei Feng
4e648b224f Revert "vk: remove subpasses to simplify descriptor set refactor (#7592)" (#7630)
This reverts commit a9793b3cf6.

Due to change in output for swiftshader
2024-03-05 17:02:20 -08:00
Powei Feng
04c7f84c6f engine: avoid leaking vertex buffer (#7628)
Previous commit [1] changed the semantic of the index to
mBufferObjects. Here we just make sure that if a buffer has been
allocated, we don't allocate another (otherwise, we'd leak).

Also cleaned up `updateBoneIndicesAndWeights` indexing

[1]: a3131a64b6
2024-03-05 13:40:18 -08:00
Sungun Park
8c31f46683 Keep supporting API level 19 (#7609)
This is a partial rollback from
d83b3858b3.

Keep supporting API level 19 for some of our clients.
2024-02-27 16:13:53 -08:00
Powei Feng
563c32b95b Merge branch 'rc/1.50.4' into release 2024-02-27 14:15:04 -08:00
Powei Feng
ab0063bc6b Bump version to 1.50.5 2024-02-27 14:15:04 -08:00
Mathias Agopian
af48bc3c74 add the disableParallelShaderCompile option to Engine::Config 2024-02-26 19:24:23 +00:00
Sungun Park
65dfac9637 Add stereoscopic type to Engine::Config (#7574)
* Add stereoscopic type to Engine::Config

This new type value will determine the algorithm used when stereoscopic
rendering is enabled.
2024-02-26 19:24:09 +00:00
Mathias Agopian
9e119937af Better fix for OOB when we have no renderable
The OOB would happen is the scene never had any renderables, in that
case the scene's SoA would stay unallocated, but the summedAreaTable
code relies on it have at least a capacity of 1.

It was incorrect to skip the RenderPass entirely because it might have
had some custom commands that needed to be executed (e.g. for applying
post-processing in subpass mode).
2024-02-21 23:55:18 -08:00
Benjamin Doherty
3e644b25f0 Fix an out-of-bounds memory access when no renderables are visible 2024-02-21 13:33:59 -08:00
Mathias Agopian
fadd5eb953 fix a uninitialized memory access when no renderable are visible 2024-02-21 10:52:50 -08:00
Powei Feng
b48b6136ba geometry: properly reference memcpy usage (#7576) 2024-02-16 15:35:01 -08:00
Sungun Park
ca0f98c513 Merge branch 'rc/1.50.3' into release 2024-02-13 00:45:01 +00:00
Sungun Park
70b87510a2 Bump version to 1.50.4 2024-02-13 00:45:01 +00:00
Mathias Agopian
31b836282d fix a typo that broke the resourceallocator cache
the cache size is given in MiB not bytes, so we needed to convert it
to bytes.
2024-02-13 00:09:17 +00:00
Powei Feng
cdd9c4aebe [release] update base64 command (#7559)
Seems like a `-i` is now necessary for the command. Note that we recently startede using mac-mx machines.
2024-02-07 12:58:16 -08:00
Powei Feng
f3a61f100c [release] update base64 command (#7559)
Seems like a `-i` is now necessary for the command. Note that we recently startede using mac-mx machines.
2024-02-07 12:57:53 -08:00
Powei Feng
0774ce6b5e Bump version to 1.50.3 2024-02-06 17:40:08 +00:00
Powei Feng
60db518b75 Merge branch 'rc/1.50.2' into release 2024-02-06 17:40:08 +00:00
Ben Doherty
3c5316f1e9 Metal: schedule PresentDrawable for destruction on the main thread (#7535) 2024-02-01 10:47:37 -08:00
Powei Feng
1f33a6efd2 Merge branch 'rc/1.50.1' into release 2024-02-01 00:41:24 +00:00
Powei Feng
4127f619e1 Bump version to 1.50.2 2024-02-01 00:41:24 +00:00
Sungun Park
b3cc4d11b8 Merge branch 'rc/1.50.0' into release 2024-01-23 21:10:19 +00:00
Sungun Park
8523f4e970 Bump version to 1.50.1 2024-01-23 21:10:19 +00:00
Sungun Park
6b7450dc0b Update material version to 50 2024-01-22 23:25:59 +00:00
Mathias Agopian
7b384fb5e8 remove all uses of our custom spinlock
This has caused issues and over time we have reduced the use of
spinlocks, it was only used in few places and we still have evidence
that it's causing ANRs.

We use utils::Mutex instead which is a low overhead mutex implementation
on Linux systems.

FIXES=[321101014]
2024-01-22 23:21:11 +00:00
Powei Feng
20dc6d479b Merge branch 'rc/1.49.3' into release 2024-01-22 11:43:54 -08:00
Powei Feng
0736f3c3b3 Add missing includes (#7501)
BUG=320668410
2024-01-17 11:08:58 -08:00
Powei Feng
6a7767f4e4 Bump version to 1.50.0 2024-01-10 13:57:25 -08:00
Powei Feng
628d387cbd Fix typo oin MaterialCompiler (#7477) 2024-01-08 15:07:07 -08:00
Eliza Velasquez
75a1c6d7a8 Generate dummy stereo variants for FL0 mats
See #7415 for a more detailed description of why this change is necessary.

The remaining variants which are filtered from FL0 materials are all related to
lighting, so further hacks like this won't be necessary.

Future work involves properly supporting differing sets of variants based on
shader language.
2024-01-08 13:04:55 -08:00
Ben Doherty
8c76370e2d Fix ostream linking error when compiling Linux DSO (#7470) 2024-01-04 10:43:50 -08:00
Benjamin Doherty
bdc15a5c2d Bump version to 1.49.3 2024-01-02 14:53:07 -08:00
Benjamin Doherty
acfe9298d9 Merge branch 'rc/1.49.2' into release 2024-01-02 14:53:06 -08:00
Benjamin Doherty
57f6e5371b Add string.h header 2024-01-02 13:23:54 -08:00
Mathias Agopian
9fa3cbfcde add a way to set a log consumer
this is a private API to capture filament's logs.
2023-12-19 12:09:28 -08:00
Mathias Agopian
c81ece5c3c cleanup 2023-12-19 12:09:23 -08:00
Benjamin Doherty
aae48c1121 Bump version to 1.49.2 2023-12-18 13:35:38 -08:00
Benjamin Doherty
918ce935b8 Merge branch 'rc/1.49.1' into release 2023-12-18 13:35:37 -08:00
Benjamin Doherty
6f37e07dba Bump MATERIAL_VERSION to 49 2023-12-18 09:57:31 -08:00
Benjamin Doherty
171b3279e0 Fix VulkanPlatformAndroidLinuxWindows for G3 2023-12-18 09:48:50 -08:00
Benjamin Doherty
b3a1cfe7c9 Bump version to 1.49.1 2023-12-11 00:13:01 -08:00
Benjamin Doherty
d273838e07 Merge branch 'rc/1.49.0' into release 2023-12-11 00:13:00 -08:00
Benjamin Doherty
a1de8c924d Update RELEASE_NOTES 2023-12-11 00:09:20 -08:00
Benjamin Doherty
72765a5b0a Fix bump-version script on Darwin 2023-12-10 19:52:39 -08:00
Benjamin Doherty
e1beabaa98 Bump MATERIAL_VERSION to 49 2023-12-10 19:43:28 -08:00
Eliza Velasquez
ebaee14b8b Generate dummy skinning variants for FL0 mats
Even if skinning is not fully implemented on FL0, we have clients which depend
on materials with skinning variants that otherwise could easily be converted to
FL0 materials. There are two proper ways to deal with this:

1. Support skinning/morphing in Feature Level 0.

2. Allow ESSL 1.0 code and ESSL 3.0 code to support different sets of variants.

However, the simplest solution is to just include skinning/morphing variants,
but disable codegen for ESSL 1.0 code, making them identical to the base
variants. This shouldn't increase the file size much due to the dictionary
deflation. Of course, skinning will not work correctly on FL0, but this has
always been the case. Future work here would be to properly implement one of the
two solutions described above.
2023-12-10 19:19:17 -08:00
Powei Feng
d4f08dafbb vk: workaround swiftshader spirv no-op issue (#7417)
Swiftshader runs spirv validation before compilation. However,
the validation does not like having Nop (no-op) in the input.
So we skip instructions instead of writing no-op for the
output of `workaroundSpecConstant`.

Also, fix issue to keep the value in the original shader if a
specialization wasn't provided.
2023-12-08 12:05:20 -08:00
Powei Feng
753fb102c4 spirv-headers: fix failed headers check (#7416)
Due to a cmake misconfiguration, we are installing spirv as part
of the release, public headers. It's now corrected.
2023-12-08 12:05:12 -08:00
Powei Feng
b219113a55 vk: spec const workaround through runtime spirv modification (#7399)
To avoid driver edge cases with spec const, we manually change the
spec const into a regular constant in the spirv.

FIXES=310603393
2023-12-08 12:05:03 -08:00
Sungun Park
9140d44b29 Bump version to 1.49.0 2023-12-05 11:39:05 -08:00
Sungun Park
8b0d65768a Merge branch 'rc/1.48.0' into release 2023-12-05 11:34:11 -08:00
Powei Feng
349bf7be38 Update MATERIAL_VERSION to 48 2023-12-01 11:01:36 -08:00
Powei Feng
a01d282f14 Add intermediate.h include to builtinResource.h (#7388) 2023-12-01 11:00:08 -08:00
Powei Feng
3c3296a114 Bump version to 1.48.0 2023-11-27 14:22:16 -08:00
Powei Feng
61501ba122 Merge branch 'rc/1.47.0' into release 2023-11-27 14:20:27 -08:00
Powei Feng
99ba40e965 Update MATERIAL_VERSION to 47 2023-11-27 19:40:34 +00:00
Eliza Velasquez
4116af7971 Enable optimizations for ESSL 1.0 code
The CL introducing the ESSL 1.0 chunk in materials inadvertently disabled
optimizations for said code. This commit reintroduces those optimizations and
fixes associated bugs which manifested. In particular, spirv-cross was
generating uints for bools; this has been fixed with a hack. Additionally,
spirv-cross is now compiled with exceptions enabled so that matc can gracefully
fail and show the code which failed to compile rather than abruptly aborting.
2023-11-27 19:32:59 +00:00
Eliza Velasquez
2fab93faff Fix typo in depth_main.fs 2023-11-27 19:32:47 +00:00
Eliza Velasquez
b92c5cab07 Incorporate feedback 2023-11-27 19:32:34 +00:00
Eliza Velasquez
8ed9678cbe Update NEW_RELEASE_NOTES.md 2023-11-27 19:32:21 +00:00
Eliza Velasquez
731e52a3c1 Add option to matc to disable ESSL 1.0 codegen 2023-11-27 19:32:03 +00:00
Eliza Velasquez
687b6da800 Enable preprocessor optimization of ESSL 1.0
Since #7358 is blocked by an upstream spirv-cross issue, we can at least do a
bit of preprocessor optimization for ESSL 1.0 code in the meantime and introduce
the FILAMENT_EFFECTIVE_VERSION preprocessor definitions.
2023-11-27 19:31:52 +00:00
Ben Doherty
64f4c097ac Remove debug code in MetalShaderCompiler (#7368) 2023-11-15 13:55:34 -08:00
Powei Feng
0191e1fe46 Bump version to 1.47.0 2023-11-14 21:38:45 -08:00
Powei Feng
21093067db Merge branch 'rc/1.46.0' into release 2023-11-14 21:34:54 -08:00
Eliza Velasquez
1b10e7d4f3 Add FILAMENT_ENABLE_FEATURE_LEVEL_0 option
This allows clients to selectively exclude feature level 0 support.
2023-11-14 16:52:26 -08:00
Eliza Velasquez
5b2d3ac225 Fix some ES2 issues
Fix specification of mipmaps when generating textures.

Fix oversight where emulated UBOs would not replace uniforms when swapped out
for another.
2023-11-14 16:29:23 -08:00
Antonio Maiorano
422dfcc1e6 Add missing include for latest glslang (#7365)
This change in glslang removes the include of "intermediate.h" from
GlslangToSpv.h:
62de186c33

As a result, the definition of "class TIntermediate" is removed, and
will fail compilation of MaterialCompiler.cpp when glslang is updated to
a version including the aforementioned change. We fix this by adding an
explicit include to this header in MaterialCompiler.cpp.

Co-authored-by: Powei Feng <powei@google.com>
2023-11-14 16:00:34 -08:00
Powei Feng
0d304393f4 Small compilation fixes (#7363)
- gltfio: Enable -Wall -Werror for gltfio_core
 - gltfio: Fix various errors that were missed warnings
 - matdbg: switch from std::atomic_uint64_t to
   std::atomic<uint64_t> for older clang
2023-11-14 14:21:52 -08:00
Mathias Agopian
57aa99e964 Fix (again) the shadow transform
- we were not using the correct field in ShadowMapManager
- we were not computing the transform correctly, it should applied
  after the local transform, not before.

FIXES=[299310624]
2023-11-13 22:29:52 -08:00
Mathias Agopian
cfc133fcf1 repair visible shadow status
FIXES=[309519433]
2023-11-13 22:29:26 -08:00
Powei Feng
8eade6be1f Revert "engine: move setFrontFaceWindingInverted from View to MaterialInstance (#7331)" (#7360)
This reverts commit 038f07cb34.
2023-11-13 22:27:56 -08:00
Powei Feng
2250664e58 Update Material_VERSION to 46 2023-11-13 10:40:02 -08:00
Benjamin Doherty
8a27cc8b7f Bump version to 1.46.0 2023-11-09 10:11:39 -08:00
Benjamin Doherty
d786d59ea1 Merge branch 'rc/1.45.1' into release 2023-11-09 10:09:56 -08:00
Ben Doherty
79116905aa Fix mix-precision quaternion conversions (#7339) 2023-11-08 12:38:23 -08:00
Benjamin Doherty
763950ec18 Revert "fix a couple shadow stability bugs"
This reverts commit 1b0db0fca2.
2023-11-08 12:33:24 -08:00
Mathias Agopian
13571868de don't use a spinlock for the HandleArena
We've seen hangs/ANR that are not well understood on that spinlock, so
for now we're going back to mutexes, which, on android, are very 
efficient under low contention (no syscall).

FIXES=[308029108]
2023-10-30 15:16:01 -07:00
Mathias Agopian
0f2c89b140 improvements to EntityManagers and Filament APIs (#7302)
* prevent public classes from being created on the stack

- we used to to this by deleting operator delete, but this prevented
  the internal "F" classes from being virtual; which can be useful
  when using EntityManger::Listener.
  now we just make the destructor protected in each class.

- EntityManger::Listener now has a virtual destructor so that
  objects could be correctly destroyed from Listener*

* improve EntityManger and Component managers

- all component managers now have the same "base" API
    - getComponentCount()
	- empty()
    - getEntity()
    - getEntities()

- Scene now has getEntityCount()

- EntityManager now has getEntityCount()

- all component manager implement gc() the same way, by calling destroy()

- SingleInstanceComponentManager::gc() that calls removeComponent() has
  been removed because it's dangerous. removeComponent() is often
  not enough, some additional cleanup might be needed.
2023-10-30 15:15:00 -07:00
Mathias Agopian
f8b70e8ec5 fix a Transform component leak in CameraManager
CameraManager creates a Transform component for each Camera component
is not already present. However, it didn't destroy the transform
component when it's itself destroyed. the leaked transform component
would eventually be garbage collected, but caused significant
slow down and memory pressure. This is because camera components are
created every frame for the shadow maps.

FIXES=[303914944]
2023-10-30 15:14:52 -07:00
Mathias Agopian
7abdea5a2e improve BlobCache API and compatibility
- the insert and retrieve handlers can now be set/unset independently.
  this could be useful for debugging.

- program caching is disabled if the GL implementation doesn't support it.

- removed unused code

FIXES=[307549547]
2023-10-30 15:13:28 -07:00
Powei Feng
cb3e808e8d Bump version to 1.45.1 2023-10-25 15:18:59 -07:00
Powei Feng
b2e0b97bad Merge branch 'rc/1.45.0' into release 2023-10-25 15:16:19 -07:00
Mathias Agopian
9c0cbed214 OpenGLBlobCache: be more robust when shader fails to compile
- don't call BlobCache if link status false
- don't assume glGetProgramiv never fails
- don't assume malloc never fails

FIXES=[307549547]
2023-10-24 20:45:52 -07:00
Powei Feng
c531a9c077 filamat: Fix MaterialInfo::userMaterialHasCustomDepth init (#7292)
Leaving it uninitialized leads to msan failure.
2023-10-24 20:45:34 -07:00
Powei Feng
2a1f762e23 Update MATERIAL_VERSION to 45 2023-10-22 22:19:41 -07:00
Ben Doherty
4dd98e63e4 Create use-after-free detector for Metal textures (#7250) 2023-10-20 17:16:55 -04:00
Ben Doherty
1b7187f427 Support stencil buffer when post-processing is disabled (#7227) 2023-10-20 17:08:30 -04:00
Benjamin Doherty
0dddd94eab Fix missing SkinningBuffer include 2023-10-18 13:45:08 -07:00
Benjamin Doherty
2ef0244266 Fix build failures due to filamat lite removal 2023-10-13 11:34:47 -07:00
Ben Doherty
0774bf9501 Remove problematic GlslangToSpv option: emitNonSemanticShaderDebugInfo (#7260) 2023-10-13 09:37:56 -07:00
Ben Doherty
8f5b2fd230 Update glslang to 277d09e679f0f4d9469c463c00cb11c6a040e65f (#7261) 2023-10-13 09:37:49 -07:00
Benjamin Doherty
274191036f Bump version to 1.45.0 2023-10-02 15:29:31 -07:00
Benjamin Doherty
13afbc2876 Merge branch 'rc/1.44.0' into release 2023-10-02 15:27:51 -07:00
Eliza Velasquez
a7bb0a60fb Revert "Remove now-redundant feature level 0 materials"
This reverts most of commit 9a6b8bf24e. The hello
triangle sample remains unreverted.

The original commit inadvertently broke screen space reflections, and perhaps
other features when the default material was used. The source of the issue is
that MaterialBuilder.cpp (correctly) filters out variants that aren't supported
in feature level 0 materials, including screen space reflections.

Unfortunately, while the "feature level 0 compatibility" feature itself was
intended to make creating duplicate materials like this redundant in client
code, unfortunately, it seems the best solution for resolving this issue is to
simply keep these redundant materials in the core.

To elaborate: clients should expect that feature level 0 materials that they
create work on /all/ feature levels /exactly/ or /close to exactly/ identically.
This includes restricting more advanced features that theoretically could be
available on a higher feature level, like SSR. It's already true that if a user
would like to optionally opt-in to a more advanced material which takes
advantage of more advanced features, they would have to maintain two separate
versions of that material: one for feature level 3 and one for feature level 1.
It should be no different in this case.

However, the materials built into the engine core are an exception to this
expectation. Given that feature level 0 was tacked on after the fact with fewer
features, there must /by necessity/ have been a new material introduced for both
the default material and the default skybox specifically for feature level 0
with fewer features than extant client apps expected to be included by default.
I imagine if filament were to be rebuilt from the ground up, this exception
wouldn't exist. However, the end result is this somewhat messy redundancy.
2023-09-29 16:49:40 -07:00
Powei Feng
0650b13358 vk: remove uneeded log in readpixels 2023-09-28 15:27:17 -07:00
Powei Feng
6cd851e77e Update MATERIAL_VERSION to 44 2023-09-28 15:27:06 -07:00
Powei Feng
87a8cb3872 Bump version to 1.44.0 2023-09-27 11:30:16 -07:00
Powei Feng
a4869eaf19 Merge branch 'rc/1.43.1' into release 2023-09-27 11:11:53 -07:00
Powei Feng
1740220f6a Update MATERIAL_VERSION to 43 2023-09-25 10:10:25 -07:00
Benjamin Doherty
5deccffdce Bump version to 1.43.1 2023-09-18 14:23:12 -07:00
Benjamin Doherty
a76eacba67 Merge branch 'rc/1.43.0' into release 2023-09-18 14:22:06 -07:00
Benjamin Doherty
ee31ca6fc0 Fix RELEASE_NOTES version 2023-09-18 14:20:30 -07:00
Benjamin Doherty
7dd6686087 Correct version to 1.43.0 2023-09-18 11:07:05 -07:00
Powei Feng
fdffd93949 vulkan: fix fence deadlock (#7173)
Should only reset fences in VulkanCommands::gc
2023-09-14 17:11:49 -07:00
Powei Feng
f0a0a9b2e1 Bump version to 1.42.3 2023-09-13 23:05:11 -07:00
Powei Feng
e743e9243f Merge branch 'rc/1.42.2' into release 2023-09-13 22:59:52 -07:00
Powei Feng
8e13d53b1e vulkan: fix swapchain leak (#7161) 2023-09-11 23:23:04 -07:00
Ben Doherty
ff274c8387 Fix incorrect SamplerParams operators (#7150) 2023-09-11 22:47:25 -07:00
Benjamin Doherty
e08e1c209b Bump version to 1.42.2 2023-09-07 17:59:26 -07:00
Benjamin Doherty
de310ed9ad Merge branch 'rc/1.42.1' into release 2023-09-07 17:55:24 -07:00
Powei Feng
d01b29fa01 vulkan: properly set bool spec onst (#7125)
We wrote a bool directly into 4 bytes (as the first byte). This has two issues:
 - the other 3 bytes are not initialized
 - should be writing VK_TRUE/FALSE instead
2023-09-01 14:17:18 -07:00
Mathias Agopian
8cba3d4366 Revert "workaround another PowerVR compiler bug "
This reverts commit 58f96be2c4.

This caused material files to increase in size significantly. It turns
out that glslang has to generate a copy for each parameter that is
passed to a function as a non-const parameter.


This revert will break IMG devices again, but that should be the case
only on debug builds. Release builds lose the const qualifier by 
virtue of going through spirv. We'll try to address this some other 
way later.
2023-09-01 14:16:59 -07:00
Ben Doherty
be1e51ad91 Update FrameCompletedCallback using directive (#7128) 2023-08-30 16:29:28 -07:00
Ben Doherty
29ce1cad84 Transition setFrameCompletedCallback to take a CallbackHandler (#7103) 2023-08-30 16:28:53 -07:00
Ben Doherty
6a967ad007 Make destroyFence asynchronous (#7127) 2023-08-30 16:28:36 -07:00
Powei Feng
fe2bb3d9a4 Merge branch 'rc/1.42.0' into release 2023-08-28 13:26:35 -07:00
Mathias Agopian
cd7973bdcf Revert "workaround another PowerVR compiler bug "
This reverts commit 58f96be2c4.

This caused material files to increase in size significantly. It turns
out that glslang has to generate a copy for each parameter that is
passed to a function as a non-const parameter.


This revert will break IMG devices again, but that should be the case
only on debug builds. Release builds lose the const qualifier by 
virtue of going through spirv. We'll try to address this some other 
way later.
2023-08-28 10:43:26 -07:00
Powei Feng
e6384e0e92 Bump version to 1.42.1 2023-08-22 13:41:42 -07:00
Powei Feng
e63dc17f54 Fix missing createFence (#7076)
Continuing from #7072
2023-08-21 10:59:42 -07:00
Powei Feng
af338cf2ec Update MaterialEnums.h (#7098) 2023-08-21 10:52:25 -07:00
Benjamin Doherty
f1d8a04337 Bump version to 1.42.0 2023-08-15 17:13:50 -07:00
Benjamin Doherty
b13497e2a0 Merge branch 'rc/1.41.0' into release 2023-08-15 17:12:01 -07:00
Powei Feng
175c9f9966 Bump version to 1.41.0 2023-08-09 10:43:02 -07:00
Powei Feng
1a50420b46 Merge branch 'rc/1.40.5' into release 2023-08-09 10:32:50 -07:00
Powei Feng
bbad75a012 vulkan: fix fence initialization (#7038)
Previously, we have a VulkanSync with a default constructor that
allows us to have sync objects that returns error when
actual fences are not yet present.  We need to replicate that
with VulkanFence since sync objects have been removed from the
API.

Fixes #7034
2023-08-07 10:17:15 -07:00
Powei Feng
25c08f19e3 vulkan: fix TSAN in readpixels (#7023) (#7028) 2023-08-02 11:00:48 -07:00
Benjamin Doherty
59063fb7b4 Bump version to 1.40.5 2023-08-01 15:39:35 -07:00
Benjamin Doherty
71f60de0ad Merge branch 'rc/1.40.4' into release 2023-08-01 15:38:37 -07:00
Powei Feng
743661109d vulkan: fix TSAN in readpixels 2023-08-01 15:35:06 -07:00
Benjamin Doherty
5014cbb023 Bump version to 1.40.4 2023-07-26 12:53:47 -07:00
Benjamin Doherty
4142e7a1cf Merge branch 'rc/1.40.3' into release 2023-07-26 12:52:12 -07:00
Benjamin Doherty
a721e648b7 Bump version to 1.40.3 2023-07-17 15:50:20 -06:00
Benjamin Doherty
358e89ef08 Merge branch 'rc/1.40.2' into release 2023-07-17 15:49:29 -06:00
Benjamin Doherty
e023e90e7a Bump version to 1.40.2 2023-07-12 13:44:52 -07:00
Benjamin Doherty
a5b5b0c3a7 Merge branch 'rc/1.40.1' into release 2023-07-12 13:43:33 -07:00
Powei Feng
b7b4d3c295 Update Material version to match 1.40.1 2023-07-10 14:27:51 -07:00
Benjamin Doherty
a445c4e156 Merge branch 'rc/1.40.0' into release 2023-06-26 13:29:06 +08:00
Benjamin Doherty
1432c59499 Add missing atomic header 2023-06-26 13:23:38 +08:00
Benjamin Doherty
4c7c10fad0 Bump version to 1.40.1 2023-06-26 13:17:45 +08:00
Benjamin Doherty
7c8a0d1967 Bump MATERIAL_VERSION to 40 2023-06-26 10:33:02 +08:00
Powei Feng
11fbacea20 Update MaterialEnums.h to v39 2023-06-20 11:57:42 -07:00
Powei Feng
8cd70454c3 Update MaterialEnums.h to v39 2023-06-20 11:56:40 -07:00
Benjamin Doherty
1d988182fc Bump version to 1.40.0 2023-06-20 23:55:00 +08:00
Benjamin Doherty
dba49f00df Merge branch 'rc/1.39.0' into release 2023-06-20 23:45:04 +08:00
Ben Doherty
89c0b44da9 Re-enable Metal half conversion, only register SimplificationPasses for Metal (#6883) 2023-06-20 14:27:44 +08:00
Ben Doherty
4f450fd5c4 Temporarily disable Metal relaxed to half pass due to spirv-cross bug (#6880) 2023-06-20 14:27:37 +08:00
Mathias Agopian
f0943cfca2 align uniform buffer to 16 bytes
this is needed on armv7 because we use alignas to get strcture-alignment,
but that also implies (to the compiler) that the structure itself
is aligned properly.
2023-06-20 14:23:47 +08:00
Mathias Agopian
9aa52b79d4 helpers to fix jank when resizing a TextureView (#6889)
There was two related issues:
- we need to "latch" the new TextureView size when its resized. That
  can only be done by recreating the EGLSurface (i.e. recreating the
  SwapChain). UiHelper now calls onNativeWindowChanged in the case of
  the TextureView resize, so clients can recreate their SwapChain.
- we also needed to make sure that all current filament frames have
  finished to render (i.e. the last eglSwapBuffers has been called) so
  that they don't pick-up a new size (this happens after
  eglSwapBuffers) that doesn't match the viewport.

Fixes b/282220665
2023-06-12 23:13:48 -07:00
Powei Feng
a82125dbbd vulkan: minor fixes (#6874)
- flush() and wait() before destroying a swapchain
 - Make sure the debug marker extension is enabled under correct
   circumstances.
 - Change shared_ptrs to unique_ptrs and raw pointers.
 - Rename most teardown methods to terminate()
2023-06-07 11:45:09 -07:00
Benjamin Doherty
24fcb299b5 Bump version to 1.39.0 2023-06-07 11:32:33 -05:00
Benjamin Doherty
753aa9ca61 Merge branch 'rc/1.38.0' into release 2023-06-07 11:31:21 -05:00
Benjamin Doherty
a33eada7ec Bump version to 1.38.0 2023-06-07 11:29:02 -05:00
Benjamin Doherty
676a2be874 Correct MATERIAL_VERSION to 37 2023-06-05 17:20:18 -05:00
Powei Feng
c95d466cdd Fix missing include (#6858) 2023-06-01 16:28:05 -07:00
Powei Feng
3d8ac384ad Update MATERIAL_VERSION to 38 (#6852) (#6854) 2023-05-31 15:00:34 -07:00
Powei Feng
57424cc7e9 Merge branch 'rc/1.37.0' into release 2023-05-30 16:22:31 -07:00
Powei Feng
78fe4ba547 vulkan: allow for headless linux builds (#6836) 2023-05-24 17:19:42 -07:00
Benjamin Doherty
a3d25cd22b Bump version to 1.37.0 2023-05-15 16:57:27 -07:00
Benjamin Doherty
56bf841bac Merge branch 'rc/1.36.0' into release 2023-05-15 16:55:48 -07:00
Ben Doherty
dfdf0db794 Fix incorrect target passed to glBindFramebuffer (#6807) 2023-05-15 15:28:44 -07:00
Benjamin Doherty
bf6bd4eca8 Fix Android CI release build 2023-05-09 13:22:47 -04:00
Benjamin Doherty
36c69dda9c Fix Android CI release build 2023-05-09 13:22:20 -04:00
Benjamin Doherty
f14fdc11f5 Bump MATERIAL_VERSION to 36 2023-05-08 18:07:13 -04:00
Benjamin Doherty
0157487b1f Bump version to 1.36.0 2023-05-08 18:06:59 -04:00
Benjamin Doherty
1716c856c3 Merge branch 'rc/1.35.0' into release 2023-05-08 18:05:07 -04:00
Benjamin Doherty
31521c70c2 Fix Android CI release build 2023-05-01 18:45:34 -04:00
Benjamin Doherty
8cac90d81e Bump MATERIAL_VERSION to 35 2023-05-01 13:37:24 -04:00
Benjamin Doherty
388b4f5efb Bump version to 1.35.0 2023-05-01 13:36:40 -04:00
Benjamin Doherty
f9b5a7f301 Merge branch 'rc/1.34.0' into release 2023-05-01 13:35:16 -04:00
Benjamin Doherty
00c78cc225 Bump MATERIAL_VERSION to 34 2023-05-01 12:20:50 -04:00
Powei Feng
2bdb8b560c vulkan: fix RenderPass size (#6775) (#6776) 2023-04-27 14:09:46 -07:00
Benjamin Doherty
a974fddd4c Bump version to 1.34.0 2023-04-25 13:10:24 -04:00
Benjamin Doherty
83a3e243da Merge branch 'rc/1.33.0' into release 2023-04-25 13:09:13 -04:00
Benjamin Doherty
f286e308bf Bump version to 1.33.0 2023-04-19 14:11:43 -04:00
Benjamin Doherty
29af3be2e3 Merge branch 'rc/1.32.4' into release 2023-04-19 14:10:10 -04:00
Mathias Agopian
6623dcbebf fix specification constant injection in glsl
- boolean where handled as int
- always cast float to float()
2023-04-17 10:29:02 -04:00
Powei Feng
89dc43f361 vulkan: fix spec constant bool size 2023-04-17 10:28:44 -04:00
Ben Doherty
b77aac43ea Fix float spec constant formatting (#6731) 2023-04-17 10:28:24 -04:00
Benjamin Doherty
0d63fa02ee Fix build when exceptions disabled 2023-04-17 10:28:00 -04:00
Benjamin Doherty
e187bc442d Bump version to 1.32.4 2023-04-11 11:19:53 -07:00
Benjamin Doherty
d62268fbfb Merge branch 'rc/1.32.3' into release 2023-04-11 11:17:47 -07:00
Benjamin Doherty
3b73e3de60 Bump version to 1.32.3 2023-04-05 12:56:23 -07:00
Benjamin Doherty
7685736d6c Merge branch 'rc/1.32.2' into release 2023-04-05 12:55:12 -07:00
Benjamin Doherty
b8a3a7f221 Bump version to 1.32.2 2023-04-05 12:53:18 -07:00
Benjamin Doherty
732628acf5 Merge branch 'rc/1.32.1' into release 2023-03-21 15:48:49 -07:00
Powei Feng
7bd00d2b30 Revert "vulkan: async readPixels (#6605)" (#6644)
This reverts commit 6f25e8ae5a.

Reason for revert: breaks clients that were expecting synchronous readPixels for vulkan
2023-03-16 13:05:48 -07:00
Benjamin Doherty
0759797e61 Include atomic in VulkanCommands.h 2023-03-15 11:15:24 -07:00
Benjamin Doherty
fddc5160c7 Bump version to 1.32.1 2023-03-14 10:48:50 -07:00
Benjamin Doherty
2a579c460f Merge branch 'rc/1.32.0' into release 2023-03-14 10:46:27 -07:00
Ben Doherty
efdc801cff Vulkan: fix stack use-after-free (#6639) 2023-03-14 10:24:18 -07:00
Benjamin Doherty
dd654c575a Bump MATERIAL_VERSION to 32 2023-03-13 14:04:13 -07:00
Benjamin Doherty
0c2599b6ca Bump version to 1.32.0 2023-03-09 10:40:39 -08:00
Benjamin Doherty
979d6742e0 Merge branch 'rc/1.31.7' into release 2023-03-09 10:39:41 -08:00
Mathias Agopian
4a7a033d04 Fix timer query breakage on webgl 2023-03-08 12:33:11 -08:00
Ben Doherty
5c2bbcb4a1 Remove compute shader assertion in GLProgram 2023-03-08 10:56:24 -08:00
Benjamin Doherty
dec903a0ee Bump version to 1.31.7 2023-03-01 11:26:50 -08:00
Benjamin Doherty
e9475b322b Merge branch 'rc/1.31.6' into release 2023-03-01 11:24:13 -08:00
Benjamin Doherty
d9aead8aac Linux CI: use clang 14 2023-02-21 16:06:48 -08:00
Powei Feng
ce148ebeb1 Update linux clang to version 10 (#6556) 2023-02-21 16:00:07 -08:00
Powei Feng
e1315fbaa7 Update CI Ubuntu version 2023-02-21 15:57:00 -08:00
Benjamin Doherty
1690549392 Bump version to 1.31.6 2023-02-21 13:18:22 -08:00
Benjamin Doherty
c73710e343 Merge branch 'rc/1.31.5' into release 2023-02-21 13:16:47 -08:00
Benjamin Doherty
092a0489da Bump version to 1.31.5 2023-02-13 11:53:24 -08:00
Benjamin Doherty
1c6279366f Merge branch 'rc/1.31.4' into release 2023-02-13 11:51:37 -08:00
Benjamin Doherty
2ac85049a9 Bump version to 1.31.4 2023-02-01 11:55:09 -08:00
Benjamin Doherty
ea428a27d1 Merge branch 'rc/1.31.3' into release 2023-02-01 11:54:04 -08:00
Benjamin Doherty
3bef718238 Bump version to 1.31.3 2023-01-24 14:28:21 -08:00
Benjamin Doherty
e9daaa0503 Merge branch 'rc/1.31.2' into release 2023-01-24 14:27:02 -08:00
Benjamin Doherty
6d3ea21993 Bump version to 1.31.2 2023-01-18 14:25:45 -08:00
Benjamin Doherty
f39127605d Merge branch 'rc/1.31.1' into release 2023-01-18 14:23:59 -08:00
Ben Doherty
db476f00f7 Vulkan: fix stack-use-after-scope ASAN error in VulkanContext.cpp (#6463) 2023-01-18 11:59:10 -08:00
Powei Feng
e54d8ec0a4 [vulkan] enumerate: Returning size = 0 is ok (#6450) 2023-01-17 10:14:45 -08:00
Benjamin Doherty
b95ac854b4 Bump version to 1.31.1 2023-01-10 12:52:49 -05:00
Benjamin Doherty
96443f6dac Merge branch 'rc/1.31.0' into release 2023-01-10 12:50:52 -05:00
Benjamin Doherty
e5e3dff9fa Fix Windows CI build 2022-12-20 11:01:49 -07:00
Benjamin Doherty
31d9da38fd Fix CI build 2022-12-20 09:40:07 -07:00
Benjamin Doherty
c5a59bb6b1 Bump version to 1.31.0 2022-12-19 11:14:41 -08:00
Benjamin Doherty
e6854148d7 Merge branch 'rc/1.30.0' into release 2022-12-19 11:12:54 -08:00
Ben Doherty
001daf0350 Fix memory leak in Scene (#6387) 2022-12-16 14:38:38 -08:00
Mathias Agopian
d26c48110d Fix Android continuous and presubmit builds
Since cmake 3.25 LINUX is automatically set based on CMAKE_SYSTEM_NAME, 
which the android cmake files are setting to "Linux". This created an
inconsistant state in our build system.
2022-12-15 11:54:33 -08:00
Mathias Agopian
15a070f0c9 Fix unused variables in release builds 2022-12-12 11:17:42 -08:00
Mathias Agopian
93230b06cf Fix Android continuous and presubmit builds
Since cmake 3.25 LINUX is automatically set based on CMAKE_SYSTEM_NAME, 
which the android cmake files are setting to "Linux". This created an
inconsistant state in our build system.
2022-12-12 10:44:49 -08:00
Mathias Agopian
4c55fc3c48 fix TransformManager high precision mode
The residual would be corrupted when using transactions.
2022-12-12 10:06:18 -08:00
Mathias Agopian
a4797a631e Fix a WebGL program link failure
WebGL complained about:

Precisions of uniform block 'ShadowUniforms' member
'ShadowUniforms.shadows.texelSizeAtOneMeter' differ between VERTEX and
FRAGMENT shaders.


this field didn't have a precision qualifier, this might be specific to
WebGL or a Chrome bug, unsure. Either we fix it by specifying all
qualifiers.
2022-11-29 23:32:21 -08:00
Mathias Agopian
5868e857aa Fix a WebGL program link failure
WebGL complained about:

Precisions of uniform block 'ShadowUniforms' member 
'ShadowUniforms.shadows.texelSizeAtOneMeter' differ between VERTEX and 
FRAGMENT shaders.


this field didn't have a precision qualifier, this might be specific to
WebGL or a Chrome bug, unsure. Either we fix it by specifying all
qualifiers.
2022-11-29 23:31:03 -08:00
Benjamin Doherty
32ba063bd7 Fix CI build 2022-11-21 16:58:37 -08:00
Benjamin Doherty
02f0839f9b Bump version to 1.30.0 2022-11-21 15:45:27 -08:00
Benjamin Doherty
e50f3c4c91 Merge branch 'rc/1.29.0' into release 2022-11-21 15:44:36 -08:00
Ben Doherty
7ca15bfc16 Use GitHub script for release asset upload (#6308) 2022-11-21 15:39:55 -08:00
Benjamin Doherty
b7b7afb62a Bump version to 1.29.0 2022-11-09 16:43:08 -08:00
Benjamin Doherty
b8ff6a9ad9 Merge branch 'rc/1.28.3' into release 2022-11-09 16:38:02 -08:00
Ben Doherty
a1dcb4f259 Skip rendering renderables with missing geometry (#6281) 2022-11-09 16:35:31 -08:00
Benjamin Doherty
c3501393fd Fix RELEASE_NOTES 2022-11-09 16:34:42 -08:00
Benjamin Doherty
a03de75a4e Update Python requirements.txt to fix CI 2022-11-04 11:35:21 -07:00
Benjamin Doherty
0c3d59aba3 Update Python requirements.txt to fix CI 2022-11-03 16:15:29 -07:00
Benjamin Doherty
ce1987f291 Fix iOS build 2022-11-01 15:10:57 -04:00
Benjamin Doherty
7eae926ed7 Bump version to 1.28.3 2022-11-01 13:03:19 -04:00
Benjamin Doherty
606af52eda Merge branch 'rc/1.28.2' into release 2022-11-01 13:02:05 -04:00
Benjamin Doherty
8ea30aea80 Update RELEASE_NOTES for 1.28.2 2022-11-01 13:00:04 -04:00
Ben Doherty
72dea695ba Fix G3 reported ubsan warning (#6257) 2022-11-01 12:52:10 -04:00
daemyung jang
1c0cf56ed0 Fix glTF breaking issue (#6239) 2022-10-28 13:08:50 -04:00
Benjamin Doherty
bcb4eb35cd Bump version to 1.28.2 2022-10-25 13:09:21 -04:00
Benjamin Doherty
bce2676335 Merge branch 'rc/1.28.1' into release 2022-10-25 13:08:12 -04:00
Benjamin Doherty
510097d722 Force spirv-cross to keep Metal argument buffer equal sized 2022-10-25 12:10:54 -04:00
Ben Doherty
5784118a12 Fix, don't use encoder.device (#6212) 2022-10-20 13:08:04 -04:00
Ben Doherty
b5de0f2d23 Metal: fix simulator regression due to arg buffers (#6181) 2022-10-18 16:29:18 -04:00
Ben Doherty
04df3f4dad Metal: fix use-after-free ASAN error (#6203) 2022-10-18 16:29:12 -04:00
Benjamin Doherty
093ca4d623 Revert Android API_LEVEL change
glDispatchCompute requires Android API level 21, however bumping our
required minimum from 19 to 21 caused some clients' builds to fail.
Commenting-out that line for now to proceed with the 1.28.0 upgrade.
2022-10-18 16:28:58 -04:00
Mathias Agopian
a3ed1558d3 fix a directional light shadowing issue
the shadow frustum could be be smaller than expected.
2022-10-14 15:42:03 -07:00
Benjamin Doherty
fe379070ae Bump version to 1.28.1 2022-10-13 12:38:40 -04:00
Benjamin Doherty
ead0a2f597 Merge branch 'rc/1.28.0' into release 2022-10-13 12:37:07 -04:00
Benjamin Doherty
5dbc593f90 Fix assertion in ShadowMap due to vertexCount 2022-10-12 18:16:53 -04:00
Ben Doherty
d47dc12bf0 G3 fixes for 1.28.0 (#6174) 2022-10-12 14:48:37 -04:00
Philip Rideout
4392f63e57 Vulkan: fix black screen regression
The VulkanProgram constructor was bailing out early and emitting a
warning because it saw that one of the stages wasn't fulfilled.
However it's okay for a pipeline to be missing a compute program.

Fixes regression that started with fabba73b1.
2022-10-12 14:48:25 -04:00
Ben Doherty
f64b7aca79 Fix Metal argument buffer encoding (#6150) 2022-10-10 10:07:41 -07:00
Ben Doherty
3762ec5750 Fix Android release build (#6133) 2022-09-30 11:48:13 -07:00
Ben Doherty
4591fdd9c0 Fix Android release build (#6133) 2022-09-30 11:47:41 -07:00
Benjamin Doherty
d3068d2a0e Bump version to 1.28.0 2022-09-29 13:13:18 -07:00
Benjamin Doherty
ca0a4bc23a Merge branch 'rc/1.27.2' into release 2022-09-29 13:12:20 -07:00
Ben Doherty
433c163c61 Fixes for 1.27.2 release (#6125) 2022-09-29 13:08:39 -07:00
Mathias Agopian
c867fda883 don't attempt to use more texture units than present
to emulate the bindless API in the gl backend we always used the highest
texture unit available. However at feature level 3, we support up to 62
textures, so the that max was bumped to 62 -- however, where we're not
on a feature level 2 device, that texture unit doesn't exist.

Instead we now always use binding 31, which is guaranteed to exist by 
EGL's minspec.
2022-09-29 12:36:28 -07:00
Ben Doherty
566540ae6d Fix generic/Mutex.h not installed on Linux (#6117) 2022-09-28 16:49:03 -07:00
Benjamin Doherty
759f490dae Bump version to 1.27.2 2022-09-20 11:06:02 -07:00
Benjamin Doherty
867d4d44f5 Merge branch 'rc/1.27.1' into release 2022-09-20 11:04:58 -07:00
Ben Doherty
65747d5877 Update glslang to c0cf8ad87 (master) (#6076) 2022-09-19 12:38:05 -07:00
Benjamin Doherty
bd357f6076 Bump version to 1.27.1 2022-09-13 10:15:12 -07:00
Benjamin Doherty
9e960b7d45 Merge branch 'rc/1.27.0' into release 2022-09-13 10:14:24 -07:00
Ben Doherty
0c54d4a6a1 Add return case to fix G3 compiler error (#6062) 2022-09-12 12:34:56 -07:00
Philip Rideout
526e846a81 gltfio: fix crash when material is unspecified 2022-09-06 22:13:19 -04:00
Philip Rideout
8bcfa373d4 gltfio: do not clear out the texture slots too early.
This broke asyncGetLoadProgress() and caused WebGL to crash reliably
because ResourceLoader got destroyed too soon.

Bug was introduced with de7dfc2ea6.

I intend to cherry pick this to rc/1.27.0, which is where it was
introduced, so there's no need to update the release notes.
2022-09-06 22:09:25 -04:00
Ben Doherty
db9a0f2c1f Fix uberarchive not included in PodSpec (#6024) 2022-09-01 12:18:20 -04:00
Benjamin Doherty
646b1e2193 Bump version to 1.27.0 2022-08-31 12:04:55 -04:00
Benjamin Doherty
41bd30f81d Merge branch 'rc/1.26.0' into release 2022-08-31 12:04:08 -04:00
Mathias Agopian
bd626aea27 material instanced property must be false by default.
this fix auto-instancing.
2022-08-26 18:28:56 -04:00
Benjamin Doherty
8a03f75485 Bump version to 1.26.0 2022-08-23 12:07:33 -04:00
Benjamin Doherty
dc9594fbdf Merge branch 'rc/1.25.6' into release 2022-08-23 12:05:44 -04:00
Benjamin Doherty
fad0b533c0 Update RELEASE_NOTES for 1.25.6 2022-08-23 12:03:28 -04:00
Benjamin Doherty
4d773e9453 Bump version to 1.25.6 2022-08-16 11:03:07 -07:00
Benjamin Doherty
e0c610b013 Merge branch 'rc/1.25.5' into release 2022-08-16 11:01:04 -07:00
Benjamin Doherty
0da4f36c33 Bump version to 1.25.5 2022-08-16 10:54:00 -07:00
Ben Doherty
11d17e1db3 Fix SamplerGroup update issue (#5928) 2022-08-16 10:47:18 -07:00
Philip Rideout
b8c318d923 WASM: Allow clients to enable pthreads.
Filament does not yet fully support threads with WASM, but this is a
baby step in that direction.

To enable experimental pthreads support, enable the WEBGL_PTHREADS CMake
option. This will enable pthreads support in `gltfio` and `utils`, which
is known to work, but not when served with GitHub Pages.

The web server must emit COOP, COEP and CORP headers, so our build
instructions now recommend the use of `emrun` for local testing.

This also changes our demos so that they do not use unpkg, which
does not work when using `emrun`, due to cross-origin restrictions.
2022-08-12 15:43:28 -07:00
Philip Rideout
e563cc6f5e gltfio: add 'detach' methods to allow ownership transfer
These new methods allow gltfio to be integrated into internal Google
libraries.
2022-08-09 14:37:44 -07:00
Benjamin Doherty
cb8914ab96 Merge branch 'rc/1.25.4' into release 2022-08-02 11:47:52 -07:00
Alan Eneev
2fecda7bdc Headless EGL: Fallback to a 24-bit depth buffer 2022-07-29 10:10:46 -07:00
Alan Eneev
543d8efb25 Fix PlatformEGLHeadless build and add a build.sh option to build EGL
I have disabled building SDL with headless EGL, because
SDL_config_minimal.h doesn't work with EGL, and I don't know how to
implement a an SDL config that would work with EGL.

I have verified that this works in a separate project, and that it
compiles in this project.

```
$ ./build.sh -e release
$ find ./out/ -name "*EGL*"
./out/cmake-release/filament/backend/CMakeFiles/backend.dir/src/opengl/platforms/PlatformEGL.cpp.o
./out/cmake-release/filament/backend/CMakeFiles/backend.dir/src/opengl/platforms/PlatformEGLHeadless.cpp.o
./out/cmake-release/libs/bluegl/CMakeFiles/bluegl.dir/src/BlueGLLinuxEGL.cpp.o
```
2022-07-29 10:10:40 -07:00
Benjamin Doherty
396b1079a7 Bump version to 1.25.4 2022-07-26 09:57:34 -07:00
Benjamin Doherty
eedcd9f8cb Merge branch 'rc/1.25.3' into release 2022-07-26 09:56:22 -07:00
Ben Doherty
ab252b210c Fix config object related build failures (#5814) 2022-07-26 09:51:55 -07:00
Benjamin Doherty
1071b8ea90 Bump version to 1.25.3 2022-07-18 15:15:03 -07:00
Benjamin Doherty
a9c5bbf185 Merge branch 'rc/1.25.2' into release 2022-07-18 15:14:02 -07:00
Philip Rideout
8dd4bff7a7 gltfio: minor fixups to prep for g3 integration. 2022-07-18 15:11:36 -07:00
Philip Rideout
77c54446af gltfio: use openLocalTransformTransaction API. 2022-07-18 15:11:30 -07:00
Benjamin Doherty
4a0bc0af57 Bump version to 1.25.2 2022-07-11 15:51:55 -07:00
Benjamin Doherty
a171e75e70 Merge branch 'rc/1.25.1' into release 2022-07-11 15:50:10 -07:00
Benjamin Doherty
f5ffa092fe Bump version to 1.25.1 2022-07-06 19:09:34 -07:00
Benjamin Doherty
8de5fdd551 Merge branch 'rc/1.25.0' into release 2022-07-06 19:07:42 -07:00
Benjamin Doherty
ecca3abe98 Bump version to 1.25.0 2022-07-01 12:09:29 -07:00
Benjamin Doherty
8570e35224 Merge branch 'rc/1.24.0' into release 2022-07-01 12:08:48 -07:00
Benjamin Doherty
84df9f9a03 Update version to 1.24.0 2022-07-01 12:03:38 -07:00
Benjamin Doherty
5f93fb9613 Update RELEASE_NOTES for 1.24.0 2022-06-30 16:37:03 -07:00
Benjamin Doherty
75f77fdbdd Metal: Allow Filament to disregard MTLTexture pixelFormat when importing 2022-06-30 16:04:28 -07:00
Ben Doherty
7825d582c2 CocoaPods: include uberz library (#5752) 2022-06-30 14:07:55 -07:00
Ben Doherty
5deb0ba933 CocoaPods: include uberz library (#5752) 2022-06-30 14:04:02 -07:00
Philip Rideout
18e917aaf2 ImGuiHelper: add support for Y flip. (#5748)
Reflects a change from Betty and should be cherry picked to v1.23.3

Users could customize the ImGuiHelper camera, but they had no control
over the scissor coordinates. This allows them to use vertically flipped
coordinates, which, unfortunately, is required for MediaPipe
integration.
2022-06-30 12:05:53 -07:00
Benjamin Doherty
a165f3890a Vulkan: Support VMA_DYNAMIC_VULKAN_FUNCTIONS off 2022-06-21 15:09:26 -07:00
Philip Rideout
f88b6d9c97 Do not trigger UB with string_view. 2022-06-20 21:11:52 -07:00
Mathias Agopian
db8ecd9952 configure render primitive pool so it works with msvc
a 64 bytes pool seems to work with both clang and msvc, unfortunately,
c++ doesn't let us know the allocator object size at compile time
for map containers, so we have to guess.
2022-06-16 13:13:33 -07:00
Benjamin Doherty
b5ec06c2d2 Fix build breakage 2022-06-15 17:05:53 -07:00
Benjamin Doherty
dfbac8385e Merge branch 'rc/1.23.2' into release 2022-06-15 11:49:06 -07:00
Ben Doherty
eaab737b2c NoopDriver: return unique handles (#5697) 2022-06-15 11:28:08 -07:00
Benjamin Doherty
45991cda0a Update RELEASE_NOTES for 1.23.2 2022-06-13 15:27:03 -07:00
Philip Rideout
09a016bb6f Remove an 'API Change' warning from one item. 2022-06-09 14:33:49 -07:00
Benjamin Doherty
31607d355d Bump version to 1.23.2 2022-06-06 15:18:57 -07:00
Benjamin Doherty
a67d50b9e2 Merge branch 'rc/1.23.1' into release 2022-06-06 15:16:53 -07:00
Benjamin Doherty
8d42f53c80 Update RELEASE_NOTES for 1.23.1 2022-06-06 15:14:59 -07:00
Benjamin Doherty
5e21a55bce Revert "iOS: implement headleass swapchain (#5486)"
This reverts commit 0e5ba60cb6.

This causes issues in G3, still need to investigate the root cause.
2022-06-06 13:17:04 -07:00
Benjamin Doherty
85930ea2e8 Bump version to 1.23.1 2022-06-01 14:58:29 -07:00
Benjamin Doherty
4b3cde8b39 Merge branch 'rc/1.23.0' into release 2022-06-01 14:55:20 -07:00
Benjamin Doherty
eedfa85355 Update RELEASE_NOTES for 1.23.0 2022-06-01 14:54:50 -07:00
Benjamin Doherty
bb54c6c807 Release Filament 1.23.0 2022-06-01 14:53:48 -07:00
Benjamin Doherty
c23f905858 Update RELEASE_NOTES for 1.23.0 2022-06-01 14:53:23 -07:00
Benjamin Doherty
8c7be0a1d0 Revert "iOS: implement headleass swapchain (#5486)"
This reverts commit 0e5ba60cb6.

This causes issues in G3, still need to investigate the root cause.
2022-05-31 11:29:38 -07:00
Benjamin Doherty
878497b3d5 Bump version to 1.23.0 2022-05-24 15:19:51 -07:00
Benjamin Doherty
a155561769 Merge branch 'rc/1.22.2' into release 2022-05-24 15:17:55 -07:00
Benjamin Doherty
8b86a0ed2e Revert "iOS: implement headleass swapchain (#5486)"
This reverts commit 0e5ba60cb6.

This causes issues in G3, still need to investigate the root cause.
2022-05-24 20:13:10 +00:00
Benjamin Doherty
26f9a9b122 Update RELEASE_NOTES for 1.22.2 2022-05-23 12:40:47 -07:00
Ben Doherty
6e5f6978fb Add ktxreader and viewer libs to CocoaPods (#5573) 2022-05-18 16:24:51 -07:00
Ben Doherty
0d31d7b2de Add ktxreader and viewer libs to CocoaPods (#5573) 2022-05-18 16:13:26 -07:00
Benjamin Doherty
dd862b7e0a Bump version to 1.22.2 2022-05-17 18:03:38 -07:00
Benjamin Doherty
52065f2cbd Merge branch 'rc/1.22.1' into release 2022-05-17 18:01:37 -07:00
Benjamin Doherty
77c02d5831 Update RELEASE_NOTES for 1.22.1 2022-05-17 17:51:37 -07:00
Ben Doherty
f7e4c8d16d Add package name back to AndroidManifest.xml to fix G3 (#5569) 2022-05-17 17:51:21 -07:00
Philip Rideout
b7410474ff Workaround: partially revert "don't issue a flush..."
This is a temporary workaround for a memory corruption issue observed on
some devices from a specific vendor. We will try to make this workaround
more targeted in a subequent change.

Partial revert for b2cdf9f2b4.
2022-05-16 10:39:55 -07:00
Benjamin Doherty
384cc4ebf6 Bump version to 1.22.1 2022-05-09 13:09:39 -07:00
Benjamin Doherty
7c0643f122 Merge branch 'rc/1.22.0' into release 2022-05-09 13:07:07 -07:00
Benjamin Doherty
58abae3067 Release Filament 1.22.0 2022-05-09 13:07:02 -07:00
Benjamin Doherty
4742693869 Update RELEASE_NOTES for 1.22.0 2022-05-09 13:04:55 -07:00
Benjamin Doherty
6c39e474ea Bump version to 1.22.0 2022-05-02 13:19:43 -04:00
Benjamin Doherty
5c8977c906 Merge branch 'rc/1.21.3' into release 2022-05-02 13:18:06 -04:00
Benjamin Doherty
6b3cc2e2f3 Update RELEASE_NOTES for 1.21.3 2022-05-02 13:12:51 -04:00
Ben Doherty
76b2edd6ea Move toCompressedFilamentEnum to Ktx1Reader header (#5493) 2022-04-29 14:50:24 -04:00
Benjamin Doherty
8ebb37d011 Bump version to 1.21.3 2022-04-25 16:58:19 -04:00
Benjamin Doherty
3366db83ef Merge branch 'rc/1.21.2' into release 2022-04-25 16:57:25 -04:00
Benjamin Doherty
5415254aac Update RELEASE_NOTES for 1.21.2 2022-04-25 16:50:53 -04:00
Benjamin Doherty
caacc61602 Bump version to 1.21.2 2022-04-13 10:21:09 -06:00
Benjamin Doherty
e902df19b2 Merge branch 'rc/1.21.1' into release 2022-04-13 10:15:50 -06:00
Benjamin Doherty
40b372dda7 Update RELEASE_NOTES for 1.21.1 2022-04-12 14:36:26 -06:00
Ben Doherty
fd330a98aa Releases: specify Python dependencies in requirements.txt file (#5402) 2022-04-08 14:35:51 -07:00
Ben Doherty
90c23a7d5d Correctly prepare color grading as subpass programs (#5384) 2022-04-04 13:24:01 -07:00
Benjamin Doherty
5710304114 Bump version to 1.21.1 2022-04-04 13:03:39 -07:00
Benjamin Doherty
0f684820bc Merge branch 'rc/1.21.0' into release 2022-04-04 13:01:35 -07:00
Benjamin Doherty
e1d2d6ade6 Update RELEASE_NOTES for 1.21.0 2022-04-04 12:58:54 -07:00
Mathias Agopian
e0b6f2ca71 Change version number to 1.21.0 2022-04-04 12:41:38 -07:00
Benjamin Doherty
2a35ee279b Bump version to 1.20.6 2022-03-28 18:47:38 -07:00
Benjamin Doherty
5abf780360 Merge branch 'rc/1.20.5' into release 2022-03-28 18:45:34 -07:00
Benjamin Doherty
181f158ea9 Update RELEASE_NOTES for 1.20.5 2022-03-28 18:42:41 -07:00
Benjamin Doherty
f4087fc81d Bump version to 1.20.5 2022-03-21 14:45:34 -07:00
Benjamin Doherty
82793f9b82 Merge branch 'rc/1.20.4' into release 2022-03-21 14:43:15 -07:00
Benjamin Doherty
537576e84a Update RELEASE_NOTES for 1.20.4 2022-03-21 14:42:35 -07:00
Benjamin Doherty
375d1f55e3 Release Filament 1.20.4 2022-03-21 14:38:14 -07:00
Benjamin Doherty
597218963f Update RELEASE_NOTES for 1.20.4 2022-03-21 14:37:17 -07:00
Philip Rideout
0d29b3ddc8 WebGL endFrame: restore additional default state. 2022-03-21 09:43:45 -07:00
Philip Rideout
e0e3b42623 WebGL: reset VAO and texture bindings when frame ends. 2022-03-21 09:43:33 -07:00
Benjamin Doherty
0995ca6614 Bump version to 1.20.4 2022-03-14 14:19:36 -07:00
Benjamin Doherty
3d741fc8d4 Merge branch 'rc/1.20.3' into release 2022-03-14 14:17:54 -07:00
Benjamin Doherty
c20772b458 Update RELEASE_NOTES for 1.20.3 2022-03-10 12:56:56 -08:00
Benjamin Doherty
4a6b659098 Bump version to 1.20.3 2022-03-07 14:12:28 -08:00
Benjamin Doherty
2b93f08ca5 Merge branch 'rc/1.20.2' into release 2022-03-07 14:10:07 -08:00
Benjamin Doherty
fca62b8fff Update RELEASE_NOTES for 1.20.2 2022-03-07 14:08:41 -08:00
Benjamin Doherty
dee6d9de2c Bump version to 1.20.2 2022-03-02 15:51:38 -08:00
Benjamin Doherty
574e3e7521 Merge branch 'rc/1.20.1' into release 2022-03-02 15:47:21 -08:00
Ben Doherty
29fdf82ac5 Make VulkanContext compatible with vk_mem_alloc dev 2022-03-02 12:10:20 -08:00
Benjamin Doherty
c8cf2a54e8 Update RELEASE_NOTES for 1.20.1 2022-03-02 11:47:51 -08:00
Ben Doherty
bfd32e67d4 Apply some clang-tidy fixes (#5281) 2022-03-02 11:43:51 -08:00
Benjamin Doherty
95915367fa Bump version to 1.20.1 2022-02-24 13:59:17 -08:00
Benjamin Doherty
b769cfda62 Merge branch 'rc/1.20.0' into release 2022-02-24 13:57:10 -08:00
Benjamin Doherty
40ac88dfed Bump MATERIAL_VERSION to 20 2022-02-24 13:53:43 -08:00
Benjamin Doherty
6d96082f07 Bump version to 1.20.0 2022-02-24 13:53:43 -08:00
Benjamin Doherty
21f913db1c Update RELEASE_NOTES for 1.20.0 2022-02-24 13:53:42 -08:00
Ben Doherty
699a578966 Add SSR variant filter to matc (#5256) 2022-02-24 10:36:06 -08:00
Philip Rideout
babbfa1394 Vulkan: remove layout checks from SwapChain.
These asserts will come back in the next Filament release, which has
much cleaner layout tracking.
2022-02-23 13:48:13 -08:00
Philip Rideout
73f0d58e10 Vulkan: fix backend tests (especially ReadPixels Y flip). 2022-02-23 11:18:29 -08:00
Philip Rideout
9cb4b74bbd Fix web apps that have multiple Filament viewers.
This fixes the emscripten binding errors that we've been seeing
with the <filament-viewer> test page, which prevented us from
including web in the last few Filament releases.

The binding errors were caused by double-initializing the emscripten
module.

I fixed this by allowing clients (e.g. FilamentViewer) to call
Filament.init() more than once. We now accumulate a list of "on ready"
callbacks that get triggered after the emscripten module becomes ready.

As far as I can tell, multiple canvases were actually always broken, and
the viewer test page worked in the past only because we got lucky.
2022-02-22 16:12:13 -08:00
Ben Doherty
f2c8456971 Attempt to fix Windows CI builds (#5205) 2022-02-15 11:12:19 -08:00
Benjamin Doherty
e571600c30 Bump version to 1.19.1 2022-02-14 13:48:59 -08:00
Benjamin Doherty
e84c94d3eb Merge branch 'rc/1.19.0' into release 2022-02-14 13:46:45 -08:00
Benjamin Doherty
e791d4818f Update RELEASE_NOTES for 1.19.0 2022-02-14 13:45:28 -08:00
Philip Rideout
cdadb43e50 WebGL: another fix for BufferDescriptor bindings.
The previous code would convert each element of the source data
into 8 bit-per-element, but we wnat to preserve the original format
that the user provides.

The new solution is to use `slice()` which is a robust way to clone
all the data in a typed array.

This fixes the new regression with Triangle that Ben caught.
2022-02-09 15:44:26 -08:00
Philip Rideout
edaff60fbf WebGL: remove buffer sharing optimization.
If emscripten grows the heap inside one of our BufferDescriptor binding
functions, then the old heap becomes "detached" and an error can
occur.

This fixes the issue seen with the Parquet demo that Ben caught.
2022-02-09 12:51:06 -08:00
Benjamin Doherty
3f64e46557 Bump version to 1.19.0 2022-02-08 09:27:14 -08:00
Benjamin Doherty
32dab23bc6 Update RELEASE_NOTES for 1.18.0 2022-02-08 09:25:41 -08:00
Benjamin Doherty
362de7dd31 Merge branch 'rc/1.18.0' into release 2022-02-08 09:22:21 -08:00
Benjamin Doherty
6b01fbb903 Correct version to 1.18.0 2022-02-08 09:08:49 -08:00
Philip Rideout
4934d9f7bc Vulkan: fix leak when apps do not draw anything. 2022-02-07 14:27:06 -08:00
Ben Doherty
ed73955b00 Initialize useLegacyMorphing to fix MSAN warning (#5164) 2022-02-07 11:28:03 -08:00
Ben Doherty
3f1f2726c4 Add a MAX_LEGACY_MORPH_TARGETS definition (#5163) 2022-02-07 11:27:45 -08:00
Philip Rideout
1a7bd7ea8d Rewrite VulkanPipelineCache (without changing its API).
All three types of caches (descriptor sets, pipelines, and pipeline
layouts) are now managed in exactly the same way. They all use an LRU
eviction scheme that is based on a count of command buffer flush
events.

Vulkan objects can only be destroyed if there are no in-flight command
buffers that reference them, so an easy way to know when it is safe to
evict a given entry is to wait for "N" flushes after its last use, where
"N" is the number of command buffers in the command buffer ring.

Another big simplification is that there are no more dirty flags,
instead we store two sets of state vectors for each type of cache: the
"currently bound" state, and the "current requirements" state.
2022-02-03 17:37:40 -08:00
Ben Doherty
946ea43436 Fix sampler overflow check in SamplerBindingMap (#5143) 2022-02-02 11:04:48 -08:00
Philip Rideout
7f42385f5f VulkanPipelineCache: fix spurious SEGV.
Fixes #5142 by replacing unsafe pointers with map keys.

One of the differences between robin_map and unordered_map is the
following:

    pointers to keys or values in the map are invalidated in the same
    way as iterators to these keys-values

Therefore it is unsafe to track the pointer to a value that is stored
in a robin_map.
2022-02-01 16:34:34 -08:00
Philip Rideout
8845ac2b75 VulkanPipelineCache: code cleanup and minor fixes.
This is mostly just code cleanup. One actual bug was the fact that the
dummy sampler was re-created every time a new pipeline layout was
created.

It also felt strange to use `auto&` to refer to a C-style array. I
changed this into a `std::array` which is more consistent with other
fixed size arrays in this class.
2022-02-01 16:34:27 -08:00
Ben Doherty
da85001d4d Support legacy morphing (#5129)
Support legacy morphing (morphing with targets supplied via VertexAttributes) for older clients. This gives clients more time to transition over to the new MorphTargetBuffer API.
2022-01-27 16:08:46 -08:00
Mathias Agopian
8d15079937 update material version to 18 2022-01-26 14:32:46 -08:00
daemyung jang
adc542b5cd Bind samplers to specified shader stages (#5036)
Co-authored-by: Ben Doherty <bendoherty@google.com>
Co-authored-by: Mathias Agopian <mathias@google.com>
2022-01-26 14:31:30 -08:00
Philip Rideout
72feb044a3 Vulkan now supports offsets when uploading texture data.
This allows `MorphStressTest` to work on Vulkan.

However, `Horse` is still broken because it provides positions but not
tangents.  Separate fix for that is coming.

Partial fix for #5109.
2022-01-26 14:31:00 -08:00
Philip Rideout
c0ba260ddf Vulkan: clean up image layout management.
This fixes validation errors and makes a first pass at simplification.
VulkanTexture now tracks image layout using RangeMap, which paves the
way for further simplification.
2022-01-26 14:30:45 -08:00
Philip Rideout
2da215e8e7 RangeMap: improve naming convention, etc. 2022-01-26 14:30:23 -08:00
Philip Rideout
4d0368b5f1 RangeMap: improve the auto-merge functionality. 2022-01-26 14:30:09 -08:00
Philip Rideout
d11c78857d utils: introduce RangeMap container and unit test.
This will allow the Vulkan backend to efficiently track the subresource
image layouts for each texture.

This is a sparse container for a series of ordered non-overlapping
integer intervals, where each interval maps to a concrete value.
2022-01-26 14:29:45 -08:00
Mathias Agopian
e829d90c4a A morphing buffer must be bound when skinning is active
This is because we're using the same program variant for skinning
and morphing, in the skinning-only case, the buffer won't be accessed
in the shader, but it must be present.

fixes #5085
2022-01-26 14:20:25 -08:00
Mathias Agopian
a8006acd33 [GL backend] fix sampler binding bug
When a program had an unused SamplerInterfaceBlock, other samplers
could be bound to the wrong TMU

Fixes #5088
2022-01-26 14:20:12 -08:00
Benjamin Doherty
86ec502040 Bump version to 1.17.1 2022-01-24 12:52:22 -08:00
Benjamin Doherty
b19a73cc50 Merge branch 'rc/1.17.0' into release 2022-01-24 12:50:22 -08:00
Benjamin Doherty
a99c695932 Update RELEASE_NOTES for 1.17.0 2022-01-24 12:45:05 -08:00
Benjamin Doherty
8cd720b53a Bump version to 1.17.0 2022-01-18 13:54:40 -08:00
Benjamin Doherty
04df79e58f Merge branch 'rc/1.16.1' into release 2022-01-18 13:53:02 -08:00
Benjamin Doherty
a4b3717762 Update RELEASE_NOTES for 1.16.1 2022-01-18 13:48:36 -08:00
Benjamin Doherty
1035e442ee Bump version to 1.16.1 2022-01-10 10:47:46 -08:00
Benjamin Doherty
60d3638f15 Merge branch 'rc/1.16.0' into release 2022-01-10 10:44:36 -08:00
Benjamin Doherty
3e7d3c9035 Update RELEASE_NOTES for 1.16.0 2022-01-10 10:41:14 -08:00
jeanlemotan
eb360be2ad Fixed cubemap update 2022-01-10 10:34:49 -08:00
Benjamin Doherty
485ac8704d Bump version to 1.16.0 2022-01-04 11:55:19 -08:00
Benjamin Doherty
dc74540423 Merge branch 'rc/1.15.2' into release 2022-01-04 11:53:02 -08:00
Benjamin Doherty
96219c22db Update RELEASE_NOTES for 1.15.2 2022-01-04 11:49:50 -08:00
Romain Guy
f3b7048775 Add missing JNI impl (#4959) 2022-01-04 11:43:19 -08:00
Romain Guy
aaed6fb376 Fix rounding math 2022-01-04 11:43:13 -08:00
Romain Guy
35a5d3310f Fix preprocessor test 2021-12-13 13:53:20 -07:00
Benjamin Doherty
9da79a1d2d Bump version to 1.15.2 2021-12-13 11:08:28 -07:00
Benjamin Doherty
595b355d1b Merge branch 'rc/1.15.1' into release 2021-12-13 11:06:45 -07:00
Benjamin Doherty
3a67d769f4 Update RELEASE_NOTES for 1.15.1 2021-12-06 16:54:28 -08:00
Benjamin Doherty
6fb536a937 Bump version to 1.15.1 2021-12-06 11:17:37 -08:00
Benjamin Doherty
bb460d78d8 Merge branch 'rc/1.15.0' into release 2021-12-06 11:14:00 -08:00
Benjamin Doherty
838835a715 Update RELEASE_NOTES for 1.15.0 2021-12-02 11:52:04 -08:00
Romain Guy
63acd53e23 Use __ANDROID__ instead of ANDROID 2021-11-30 11:15:49 -08:00
Romain Guy
fcd2d0457b Workaround for a build system issue 2021-11-30 11:15:42 -08:00
Benjamin Doherty
58fc26461b Bump version to 1.15.0 2021-11-29 14:08:28 -08:00
Benjamin Doherty
fd82f6b04e Merge branch 'rc/1.14.2' into release 2021-11-29 14:07:03 -08:00
Benjamin Doherty
cef3200533 Add additional RELEASE_NOTES for 1.14.2 2021-11-29 10:21:56 -08:00
Ben Doherty
634500c398 Fix, avoid divide-by-zero inside makeBone (#4889) 2021-11-24 16:29:33 -08:00
Ben Doherty
b3e294ac54 Fix Metal depth comparison initialization (#4886) 2021-11-23 12:09:43 -08:00
Benjamin Doherty
2bf7535ad0 Update RELEASE_NOTES for 1.14.2 2021-11-22 10:16:00 -08:00
Benjamin Doherty
3315f75de9 Bump version to 1.14.2 2021-11-22 10:12:44 -08:00
Benjamin Doherty
bbe7dbfa92 Merge branch 'rc/1.14.1' into release 2021-11-22 10:11:06 -08:00
Benjamin Doherty
5697922a65 Update RELEASE_NOTES for 1.14.1 2021-11-17 12:04:26 -08:00
Ben Doherty
4da83df2b9 Fix material compilation error with device vertex domain (#4865)
A recent refactor was causing the following error when the vertex domain
was set to `device`:
```
ERROR: main.vs:23: 'material' : undeclared identifier
ERROR: main.vs:23: 'materialVertex' : no matching overloaded function found
```
2021-11-17 12:03:55 -08:00
Ben Doherty
8f156d6588 Android: re-enable VSM cascade fix (#4863) 2021-11-17 10:19:09 -08:00
Benjamin Doherty
cec0871c11 Bump version to 1.14.1 2021-11-15 10:09:45 -08:00
Benjamin Doherty
41a809368b Merge branch 'rc/1.14.0' into release 2021-11-15 10:07:56 -08:00
Romain Guy
ea53eb9290 Skip task incompatible with configuration caching (#4831) 2021-11-09 15:56:00 -08:00
Benjamin Doherty
05875057c9 Update RELEASE_NOTES for 1.14.0 2021-11-09 15:51:13 -08:00
Benjamin Doherty
44125926d1 Disable configuration-cache 2021-11-08 17:05:34 -08:00
Benjamin Doherty
60734349de Bump version to 1.14.0 2021-11-08 11:52:50 -08:00
Benjamin Doherty
fbfd5ec0ec Merge branch 'rc/1.13.0' into release 2021-11-08 11:50:19 -08:00
Ben Doherty
a74a95cc65 Call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (better fix) (#4779) 2021-11-04 13:28:17 -07:00
Benjamin Doherty
bc0ea16ff0 Update RELEASE_NOTES for 1.13.0 2021-11-02 13:15:53 -07:00
Mathias Agopian
b2dc8aa84c Fix typo that broke the directional shadowmap 2021-11-02 13:11:44 -07:00
Benjamin Doherty
9987e8b6ab Bump version to 1.13.0 2021-11-01 14:59:11 -07:00
Benjamin Doherty
0d9bdcc008 Merge branch 'rc/1.12.11' into release 2021-11-01 14:55:58 -07:00
Benjamin Doherty
b5c634045e Update RELEASE_NOTES for 1.12.11 2021-10-28 16:13:50 -07:00
Ben Doherty
1f05531d53 Call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (better fix) (#4779) 2021-10-28 16:02:23 -07:00
Benjamin Doherty
88f382f0e3 Revert "refactor colorgrading materials"
This reverts commit fb86a77cf8.
2021-10-28 15:56:50 -07:00
Benjamin Doherty
3e59925900 Remove problematic configuration-cache setting for release build 2021-10-28 15:56:26 -07:00
Benjamin Doherty
ea404f8d4f Remove problematic configuration-cache setting for release build 2021-10-26 10:09:51 -07:00
Benjamin Doherty
602a550d93 Bump version to 1.12.11 2021-10-25 12:30:37 -07:00
Benjamin Doherty
12abbe2d23 Merge branch 'rc/1.12.10' into release 2021-10-25 11:06:18 -07:00
Benjamin Doherty
fb0ee97588 Update RELEASE_NOTES for 1.12.10 2021-10-25 11:00:06 -07:00
Ben Doherty
56ef48c9c3 Fix, call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (#4749) 2021-10-25 10:39:24 -07:00
Benjamin Doherty
47c3dd3dd1 Revert "refactor colorgrading materials"
This reverts commit fb86a77cf8.
2021-10-25 10:37:52 -07:00
Benjamin Doherty
c181648bfa Bump version to 1.12.10 2021-10-20 12:15:51 -07:00
Benjamin Doherty
0cf78b3abe Merge branch 'rc/1.12.9' into release 2021-10-20 12:12:33 -07:00
Ben Doherty
22889a7ad9 Fix VirtualMachineEnv.cpp with older JNI versions (#4752) 2021-10-20 11:16:55 -07:00
Ben Doherty
a14451d0ac Fix, call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (#4749) 2021-10-20 10:41:34 -07:00
Benjamin Doherty
5dfdab10b7 Revert "refactor colorgrading materials"
This reverts commit fb86a77cf8.
2021-10-19 16:13:21 -07:00
Benjamin Doherty
d6f2e3b8e9 Update RELEASE_NOTES for 1.12.9 2021-10-14 18:22:20 -07:00
Benjamin Doherty
df30517743 Bump version to 1.12.9 2021-10-11 11:06:43 -07:00
Benjamin Doherty
8f80643c1a Merge branch 'rc/1.12.8' into release 2021-10-11 11:02:56 -07:00
Benjamin Doherty
5aea9be2fb Update RELEASE_NOTES for 1.12.8 2021-10-07 11:03:45 -07:00
Benjamin Doherty
ad02e483d0 Bump version to 1.12.8 2021-10-04 10:26:57 -07:00
Benjamin Doherty
f463d53036 Merge branch 'rc/1.12.7' into release 2021-10-04 10:21:42 -07:00
Benjamin Doherty
b8d4408524 Update RELEASE_NOTES for 1.12.7 2021-10-04 10:18:56 -07:00
Benjamin Doherty
fef70be848 Bump version to 1.12.7 2021-09-27 11:15:58 -07:00
Benjamin Doherty
bdb12d9b24 Merge branch 'rc/1.12.6' into release 2021-09-27 11:12:42 -07:00
Ben Doherty
43ad283a83 Fix, missing call to setTransparencyMode (#4674) 2021-09-24 13:32:49 -07:00
Benjamin Doherty
2e4936afc4 Revert "fix a race in jobsystem"
This reverts commit 2feb0ad325.
2021-09-24 11:24:44 -07:00
Benjamin Doherty
891ffabd11 Update RELEASE_NOTES for 1.12.6 2021-09-23 17:25:25 -07:00
Ben Doherty
e2c19498b4 Metal: don't call createTextureViewWithsSwizzle directly (#4662) 2021-09-23 11:28:04 -07:00
Ben Doherty
c32630b265 Fix MetalBlitter crash when shader contains warnings (#4663) 2021-09-23 11:27:56 -07:00
Alexey Pelykh
bf21e78d02 Podspec: include headers in nested directories (#4658) 2021-09-22 16:48:12 -07:00
Benjamin Doherty
525d4e08a3 Bump version to 1.12.6 2021-09-20 10:17:18 -07:00
Benjamin Doherty
2e9bf6d694 Merge branch 'rc/1.12.5' into release 2021-09-20 10:14:37 -07:00
Benjamin Doherty
e845f01d85 Update RELEASE_NOTES for 1.12.5 2021-09-20 10:10:56 -07:00
Benjamin Doherty
bef48be7b4 Bump version to 1.12.5 2021-09-13 10:47:09 -07:00
Benjamin Doherty
b54fdc9e6e Merge branch 'rc/1.12.4' into release 2021-09-13 10:43:06 -07:00
Benjamin Doherty
cedbf2e30b Update RELEASE_NOTES for 1.12.4 2021-09-13 10:40:55 -07:00
Benjamin Doherty
592f8d1b0d Bump version to 1.12.4 2021-09-08 11:05:44 -07:00
Benjamin Doherty
29612a684e Merge branch 'rc/1.12.3' into release 2021-09-08 11:03:53 -07:00
Benjamin Doherty
e6d5807399 Bump version to 1.12.3 2021-08-30 11:46:51 -07:00
Benjamin Doherty
fa2553251f Merge branch 'rc/1.12.2' into release 2021-08-30 11:44:00 -07:00
Benjamin Doherty
7387718852 Update RELEASE_NOTES for 1.12.2 2021-08-30 11:41:52 -07:00
Ben Doherty
a503a6209a Fix regression with clipSpaceTransform (#4552) 2021-08-26 14:14:58 -07:00
Ben Doherty
ce3e5f74e8 Fix Metal STREAM buffers (#4543) 2021-08-25 09:48:34 -07:00
Ben Doherty
f37112358e Fix missing bookkeeping in bindUniformBufferRange (#4538) 2021-08-24 09:51:40 -07:00
Benjamin Doherty
f368b14621 Bump version to 1.12.2 2021-08-23 12:41:33 -07:00
Benjamin Doherty
6960b1148a Merge branch 'rc/1.12.1' into release 2021-08-23 12:39:38 -07:00
Benjamin Doherty
3cc23aac25 Update RELEASE_NOTES for 1.12.1 2021-08-23 10:45:59 -07:00
Benjamin Doherty
11dc8740f2 Fix stack-use-after-scope error 2021-08-20 15:40:06 -07:00
Ben Doherty
4b797cff88 Windows: fix incorrect CRT flags with Visual Studio generators (#4516) 2021-08-20 10:56:41 -07:00
Ben Doherty
fe1c1736cd Fix, potential null dereferences in MetalBlitter (#4481) 2021-08-10 16:30:11 -07:00
Benjamin Doherty
4058ef5f09 Bump version to 1.12.1 2021-08-09 12:06:47 -07:00
Benjamin Doherty
d25ca01624 Merge branch 'rc/1.12.0' into release 2021-08-09 12:03:33 -07:00
Benjamin Doherty
d96f87dbbf Update RELEASE_NOTES for 1.12.0 2021-08-09 12:01:46 -07:00
Ben Doherty
8a2e31023f Attempt to fix TSAN failure in ColorGrading.cpp (#4447) 2021-08-05 11:54:07 -07:00
Benjamin Doherty
1ea8e171d9 Bump version to 1.12.0 2021-08-03 11:18:56 -07:00
Benjamin Doherty
e2be3dd0ac Merge branch 'rc/1.11.2' into release 2021-08-03 11:15:19 -07:00
Romain Guy
1c51164e7b Fix inverse tone mapping issues (#4437)
Bring color grading back into the Rec.709 color space to match
previous behaviors. This change also implements an exact inverse
tone map function for the "Filmic" operator.
2021-08-02 20:54:44 -07:00
Benjamin Doherty
f190f03530 Update RELEASE_NOTES for 1.11.2 2021-08-02 11:17:42 -07:00
Ben Doherty
055fc7cbc1 Attempt to fix Windows CI by turning off concurrent builds (#4395) 2021-07-30 14:09:07 -07:00
Ben Doherty
9073fc3dc3 Attempt to fix Windows CI by turning off concurrent builds (#4395) 2021-07-28 10:49:37 -07:00
Ben Doherty
2409dc9bc4 Expose Engine::flush (#4385) 2021-07-26 15:09:14 -07:00
Benjamin Doherty
6586c8d70b Bump version to 1.11.2 2021-07-26 12:50:29 -07:00
Benjamin Doherty
ac0c94da69 Merge branch 'rc/1.11.1' into release 2021-07-26 12:48:36 -07:00
Ben Doherty
d19d6a72b0 Expose Engine::flush (#4385) 2021-07-26 12:10:19 -07:00
Benjamin Doherty
c81b5d98ef Update RELEASE_NOTES for 1.11.1 2021-07-26 10:05:41 -07:00
Mathias Agopian
756866675f fix an issue where a sampler could fail to be updated
SamplerGroup was comparing texture handles to decide if a texture needed
to be updated, however, texture handles are (quickly) recycled and
therefore can't be used for that purpose. e.g. if a texture is destroyed,
its handle could be reused quickly by another texture, if that texture 
is now set on the SamplerGroup, it will ignore it, thinking it's not
different.
2021-07-21 14:46:44 -07:00
Benjamin Doherty
ebcd4925f7 Bump version to 1.11.1 2021-07-19 10:24:01 -07:00
Benjamin Doherty
13bed4fdf9 Merge branch 'rc/1.11.0' into release 2021-07-19 10:20:29 -07:00
Benjamin Doherty
1dae5c6b6c Update RELEASE_NOTES for 1.11.0 2021-07-19 10:18:07 -07:00
Benjamin Doherty
8e6663e4b0 Bump version to 1.11.0 2021-07-12 10:49:43 -07:00
Benjamin Doherty
ba804444b8 Merge branch 'rc/1.10.7' into release 2021-07-12 10:47:12 -07:00
Benjamin Doherty
58cfb85004 Update RELEASE_NOTES for 1.10.7 2021-07-12 10:45:24 -07:00
Mathias Agopian
ab46481b45 Fix colorgrading as subpass
We were inserting the colorgrading subpass command between the
refracted and blended objects, instead of after all of them.

Another bad side effect of this was to trigger the refraction pass for
no reason.
2021-07-12 10:35:01 -07:00
Mathias Agopian
4296782399 don't crash when refraction pass is empty 2021-07-12 09:53:37 -07:00
Benjamin Doherty
ef375a7103 Bump version to 1.10.7 2021-07-07 11:02:30 -07:00
Benjamin Doherty
fd258b7765 Merge branch 'rc/1.10.6' into release 2021-07-07 10:59:12 -07:00
Benjamin Doherty
147de8d372 Update RELEASE_NOTES for 1.10.6 2021-07-07 10:57:25 -07:00
Philip Rideout
eb2a1928b6 ShadowMapManager: fix MSAN use-of-uninitialized-value.
The operator!= in std::array compares SPLIT_COUNT elements, which
is potentially greater than cascadeCount, which was the number of
initialized elements in splitPercentages.
2021-07-07 10:51:18 -07:00
Benjamin Doherty
35b033102f Bump version to 1.10.6 2021-06-28 12:07:58 -07:00
Benjamin Doherty
7bc65421a9 Merge branch 'rc/1.10.5' into release 2021-06-28 12:04:31 -07:00
Benjamin Doherty
736514cf37 Update RELEASE_NOTES for 1.10.5 2021-06-28 12:04:27 -07:00
Mathias Agopian
db0158dae8 fix webgl build
we need to select opengl on webgl.
2021-06-28 08:27:46 -07:00
Benjamin Doherty
e706695ed1 Bump version to 1.10.5 2021-06-21 11:18:26 -07:00
Benjamin Doherty
e8877ffe2d Merge branch 'rc/1.10.4' into release 2021-06-21 11:16:10 -07:00
Benjamin Doherty
1fd5d9dae6 Update RELEASE_NOTES for 1.10.4 2021-06-21 11:14:35 -07:00
Ben Doherty
cd48089318 filament-utils-android: fix string literal conversions (#4137) 2021-06-15 16:19:32 -06:00
Benjamin Doherty
6379ab22c9 Bump version to 1.10.4 2021-06-14 11:06:42 -06:00
Benjamin Doherty
0bf02b75d5 Merge branch 'rc/1.10.3' into release 2021-06-14 11:04:25 -06:00
Benjamin Doherty
c4259b5598 Update RELEASE_NOTES for 1.10.3 2021-06-14 11:02:45 -06:00
Ben Doherty
6b3c1179bc Include sample-gltf-viewer with Android releases (#4099) 2021-06-08 10:41:48 -07:00
Philip Rideout
c1a0e61e8e Fix FixedCapacityVector destructor.
std::allocator::deallocate() expects the same value that was given
during allocate().

Interestingly, this bug did not manifest any issues (even with ASAN) on
some platforms.
2021-06-07 15:56:33 -07:00
Benjamin Doherty
fc06298ed4 Bump version to 1.10.3 2021-06-07 11:22:04 -07:00
Benjamin Doherty
4ca87b188c Merge branch 'rc/1.10.2' into release 2021-06-07 11:19:51 -07:00
Benjamin Doherty
f1f60c3e0d Turn off warnings as errors for spirv-tools 2021-06-07 11:18:56 -07:00
Benjamin Doherty
76d21b56af Update RELEASE_NOTES for 1.10.2 2021-06-07 11:18:09 -07:00
Benjamin Doherty
0ab0e50a4f Turn off warnings as errors for spirv-tools 2021-06-02 11:16:42 -07:00
Benjamin Doherty
34f4c06a5c Bump version to 1.10.2 2021-06-01 11:17:32 -07:00
Benjamin Doherty
6de36f1e53 Merge branch 'rc/1.10.1' into release 2021-06-01 11:15:49 -07:00
Benjamin Doherty
2a9a3b1ac2 Update RELEASE_NOTES for 1.10.1 2021-06-01 11:13:04 -07:00
Benjamin Doherty
84b73a3770 Bump version to 1.10.1 2021-05-24 10:52:02 -07:00
Benjamin Doherty
662a10e273 Merge branch 'rc/1.10.0' into release 2021-05-24 10:49:10 -07:00
Benjamin Doherty
ecce02502e Update RELEASE_NOTES for 1.10.0 2021-05-24 10:47:39 -07:00
Philip Rideout
d17875aea1 ImGuiHelper: fix support for custom images.
The texture binding in the material instance needs to be restored to the
glyph atlas when a custom image is not in use.
2021-05-21 12:49:37 -07:00
Philip Rideout
b8897a68f9 matc: detect missing end brace.
matc was failing to report certain kinds of syntax errors and would
read out-of-bounds memory.

This change casuses the flare material to fail.
2021-05-21 09:20:33 -07:00
Ben Doherty
84efd4871e API CHANGE: remove some Camera, Engine, and View deprecated APIs (#3965) 2021-05-19 12:02:13 -07:00
Benjamin Doherty
85ea5a6b70 Bump version to 1.10.0 2021-05-17 11:00:42 -07:00
Benjamin Doherty
77891acb92 Merge branch 'rc/1.9.25' into release 2021-05-17 10:57:30 -07:00
Benjamin Doherty
74fe102035 Update RELEASE_NOTES for 1.9.25 2021-05-17 10:54:38 -07:00
Philip Rideout
25cc554925 WASM: fix "Missing field" error for lensFlare. 2021-05-17 10:06:56 -07:00
Ben Doherty
d787a521b5 Fix DIST_DIR setting for Windows builds (#3945) 2021-05-12 11:16:30 -07:00
Ben Doherty
46e52c71e1 Fix DIST_DIR setting for Windows builds (#3945) 2021-05-12 11:15:49 -07:00
Philip Rideout
1dad27a172 Repair WebGL and fix potential INVALID_OPERATION.
We should take care not to call glVertexAttribPointer when there is
no bound ARRAY_BUFFER (i.e. when its binding is zero).

This fixes the black screen seen with some WebGL samples after
the recent memory leak fix related to the new BufferObject API.
2021-05-10 13:38:56 -07:00
Benjamin Doherty
60d230b380 Bump version to 1.9.25 2021-05-07 21:42:48 -07:00
Benjamin Doherty
d7cb38e706 Merge branch 'rc/1.9.24' into release 2021-05-07 21:39:17 -07:00
Benjamin Doherty
ce00cca6ee Update RELEASE_NOTES for 1.9.24 2021-05-07 21:36:49 -07:00
Philip Rideout
d627d57bad Second memory leak fix. (#3906)
Fixes #3888.
2021-05-06 14:25:46 -07:00
Philip Rideout
8ffc776f1c Fix horrible memory leak in the GL driver. (#3894)
This leak was introduced in the following PR on April 7.
https://github.com/google/filament/pull/3775

The guilty party has been contacted and properly admonished for his
transgression.

This was tested by adding the following code after applyAnimation in
gltf_viewer.cpp

        static int nframes = 0;
        if (!gpath.empty() && nframes++ > 100) {
            static int count = 0;
            printf("reloading %d\n", count++);
            nframes = 0;
            app.resourceLoader->asyncCancelLoad();
            app.resourceLoader->evictResourceData();
            app.viewer->removeAsset();
            app.assetLoader->destroyAsset(app.asset);
            loadAsset(gpath, app);
            loadResources(gpath, app);
        }
2021-05-04 18:22:08 -07:00
Benjamin Doherty
be032b52c1 Bump version to 1.9.24 2021-05-03 10:42:19 -07:00
Benjamin Doherty
4388e81e5f Merge branch 'rc/1.9.23' into release 2021-05-03 10:40:49 -07:00
Benjamin Doherty
71a185d139 Update RELEASE_NOTES for 1.9.23 2021-05-03 10:38:59 -07:00
Benjamin Doherty
d2cf5985ac Bump version to 1.9.23 2021-04-26 10:55:10 -07:00
Benjamin Doherty
debcbb8e5c Merge branch 'rc/1.9.22' into release 2021-04-26 10:52:43 -07:00
Benjamin Doherty
b9dd62c7d3 Update RELEASE_NOTES for 1.9.22 2021-04-26 10:47:11 -07:00
Benjamin Doherty
dc2b430f34 Bump version to 1.9.22 2021-04-26 10:39:16 -07:00
Benjamin Doherty
e5ef4e8868 Update RELEASE_NOTES for 1.9.21 2021-04-19 11:36:37 -07:00
Benjamin Doherty
c0d6cd3ac3 Merge branch 'rc/1.9.21' into release 2021-04-19 11:34:23 -07:00
Benjamin Doherty
b63ab2dc19 Update RELEASE_NOTES for 1.9.21 2021-04-19 11:32:31 -07:00
Benjamin Doherty
5d8dad561c Bump version to 1.9.21 2021-04-12 11:38:27 -07:00
Benjamin Doherty
8933be1ae2 Merge branch 'rc/1.9.20' into release 2021-04-12 11:36:17 -07:00
Benjamin Doherty
6b66b48b1d Update RELEASE_NOTES for 1.9.20 2021-04-12 11:35:45 -07:00
Benjamin Doherty
9c23eb6e33 Release Filament 1.9.20 2021-04-12 11:34:39 -07:00
Benjamin Doherty
baea54a3fc Update RELEASE_NOTES for 1.9.20 2021-04-12 09:20:31 -07:00
Benjamin Doherty
d9f800454c Bump version to 1.9.20 2021-04-05 11:14:17 -07:00
Benjamin Doherty
f9ee0de07a Merge branch 'rc/1.9.19' into release 2021-04-05 11:11:13 -07:00
Benjamin Doherty
2786d0a9f7 Update RELEASE_NOTES for 1.9.19 2021-04-05 11:10:50 -07:00
Benjamin Doherty
491e8032e6 Release Filament 1.9.19 2021-04-05 11:10:20 -07:00
Benjamin Doherty
ef3f13f5d3 Update RELEASE_NOTES for 1.9.19 2021-04-05 11:09:38 -07:00
Benjamin Doherty
bcb5b2d790 Implement Metal BufferObjects 2021-04-05 11:01:36 -07:00
Ben Doherty
02de3f2e2a Fix, regression with Metal buffers (#3715) 2021-03-29 14:21:34 -07:00
Benjamin Doherty
0e7bb53c07 Bump version to 1.9.19 2021-03-29 11:09:32 -07:00
Benjamin Doherty
759109d478 Merge branch 'rc/1.9.18' into release 2021-03-29 11:06:55 -07:00
Benjamin Doherty
54d5af6edf Update RELEASE_NOTES for 1.9.18 2021-03-29 11:04:57 -07:00
Philip Rideout
38fbe47ced RenderTarget: fix NPE when depth is not present.
This fixes a recent regression that would occur when a RenderTarget
does not have a depth attachment.
2021-03-29 10:32:22 -07:00
Benjamin Doherty
f066c925ba Bump version to 1.9.18 2021-03-22 10:16:34 -07:00
Benjamin Doherty
994fdf4e1d Merge branch 'rc/1.9.17' into release 2021-03-22 10:12:20 -07:00
Benjamin Doherty
50b50d65e3 Update RELEASE_NOTES for 1.9.17 2021-03-22 10:11:02 -07:00
Mathias Agopian
0aaa985649 Fix a hang in JobSystem
The hang was caused by a subtle race. When a job is completed, its 
thread must signal all the threads that might be waiting on this job.
The signaling code was attempting to signal only the minimum number
of threads -- this was important especially in the case where no threads
were waiting, then the call to notify() could be avoided.

Unfortunately, for performance reasons we're not calling notify() with
the condition lock held, this meant that between the time the number of 
waiting threads was latched and the time of the notify() call, more
threads could enter their condition variable wait(), and it would
then be possible for these threads to wake up, instead of the thread
we were trying to wake up (the one waiting on the job).

It would then get stuck forever.

This bug was introduced in 2df639133b


Also add some debugging code for this kind of failure (disabled)
2021-03-18 09:57:25 -07:00
Benjamin Doherty
29564f8eae Bump version to 1.9.17 2021-03-15 10:15:25 -07:00
Benjamin Doherty
c15db68a5b Merge branch 'rc/1.9.16' into release 2021-03-15 10:12:56 -07:00
Benjamin Doherty
3452fb3e56 Update RELEASE_NOTES for 1.9.16 2021-03-15 10:10:40 -07:00
Mathias Agopian
35eb8e7be1 Revert GL backend handle tracking
This wasn't very useful in the first place because we're recycling
handles very quickly. Additionally there was a race condition
which cause false positives.

This reverts commit bc6acd5c5a.
This reverts commit 3a15756c78.
2021-03-12 13:02:55 -08:00
Mathias Agopian
834b774128 Fixes some issues with imported rendertargets
We were not declaring the attachments it was using.

Fixes #3628
2021-03-12 08:26:16 -08:00
Benjamin Doherty
5aa0eb9f9d Bump version to 1.9.16 2021-03-08 10:09:14 -08:00
Benjamin Doherty
d9a6e2e649 Merge branch 'rc/1.9.15' into release 2021-03-08 10:07:00 -08:00
Benjamin Doherty
cb823b16a1 Update RELEASE_NOTES for 1.9.15 2021-03-08 10:05:19 -08:00
Ben Doherty
0bd41e877e Downgrade Linux GitHub Actions environment to fix error (#3588) 2021-03-01 11:21:11 -08:00
Benjamin Doherty
ecc3e73967 Bump version to 1.9.15 2021-03-01 11:13:44 -08:00
Benjamin Doherty
464b4c24f9 Merge branch 'rc/1.9.14' into release 2021-03-01 11:11:53 -08:00
Benjamin Doherty
32367516e8 Update RELEASE_NOTES for 1.9.14 2021-03-01 11:10:06 -08:00
Philip Rideout
1709a55606 filamat: Fix data race with SPIRV error registrations. 2021-02-26 10:34:36 -08:00
Benjamin Doherty
58b4455979 Bump version to 1.9.14 2021-02-22 10:32:56 -08:00
Benjamin Doherty
ea1dede19c Merge branch 'rc/1.9.13' into release 2021-02-22 10:29:57 -08:00
Benjamin Doherty
20ea3381fa Update RELEASE_NOTES for 1.9.13 2021-02-22 10:28:21 -08:00
Philip Rideout
7aa6fccd7c Modernize Python print syntax to appease external codebase. 2021-02-19 11:38:18 -08:00
Philip Rideout
adbd54f4f8 Change abs() to std::abs to appease external codebase. 2021-02-19 11:38:18 -08:00
Philip Rideout
9d54261f18 Move vk_mem_alloc to its own cpp.
This will improve parity between the GitHub repo and its sister codebase
within Google.
2021-02-19 11:38:18 -08:00
Philip Rideout
a97757c9ae Avoid uninitialized reads in computeVisibilityMasks.
I verified that this code is not enabled in our GitHub builds, and I
verified that the MSAN error goes away.
2021-02-19 11:38:18 -08:00
Philip Rideout
7c79d9f89d Remove some Windows line endings.
These line endings cause annoying diffs when comparing Filament's GitHub
source with its twin sister within Google.
2021-02-19 11:38:18 -08:00
Benjamin Doherty
bf0914f813 Bump version to 1.9.13 2021-02-16 10:48:24 -08:00
Benjamin Doherty
b96bc30fbd Merge branch 'rc/1.9.12' into release 2021-02-16 10:44:13 -08:00
Benjamin Doherty
62b50eb8ba Update RELEASE_NOTES for 1.9.12 2021-02-16 10:42:41 -08:00
Ben Doherty
b4932e384a matc: Use consistent params for semantic code analysis (#3524)
When running semantic analysis on a material, we were arbitrarily choosing the first code gen permutation to analyze. So, running matc with arguments --api metal versus --api all would run analysis on slightly different shader code. This causes bugs when flags passed to glslang differ during semantic analysis. This change updates all semantic analysis to always use the same shader code.
2021-02-08 14:06:47 -08:00
Benjamin Doherty
5e68dc5f8d Bump version to 1.9.12 2021-02-08 09:58:15 -08:00
Benjamin Doherty
f222f1b925 Merge branch 'rc/1.9.11' into release 2021-02-08 09:51:08 -08:00
Ben Doherty
22e4a54782 Update RELEASE_NOTES for 1.9.11 2021-02-08 09:50:23 -08:00
Benjamin Doherty
1289922c5f Release Filament 1.9.11 2021-02-08 09:48:50 -08:00
Ben Doherty
2839c352b8 Update RELEASE_NOTES for 1.9.11 2021-02-08 09:47:18 -08:00
Ben Doherty
6a01cbc312 Draft: fix TSAN issue by using lock in ColorGrading constructor (#3510)
This is a second attempt to fix Google3 TSAN failures seen inside of the ColorGrading constructor.

Related first attempt: #3462
2021-02-05 14:06:40 -08:00
Benjamin Doherty
6193156556 Bump version to 1.9.11 2021-02-01 11:49:12 -08:00
Benjamin Doherty
fe23aa917d Merge branch 'rc/1.9.10' into release 2021-02-01 11:45:47 -08:00
Benjamin Doherty
eb8a29a332 Update RELEASE_NOTES for 1.9.10 2021-02-01 11:45:17 -08:00
Ben Doherty
0626902530 Fix sporatic data race warning seen in Google3 (#3462) 2021-01-27 16:40:16 -08:00
Philip Rideout
042bfe2597 Partial fix for MSVC build. 2020-12-14 12:15:06 -08:00
Ben Doherty
97133f3591 Fix Windows iterator issue in Zip2Iterator and StructureOfArrays (#3322) 2020-12-14 12:14:53 -08:00
Philip Rideout
d06cc4390e filamat: minify struct fields.
This shrinks the arm64 so file by 24 KiB.
2020-12-14 11:19:43 -08:00
Philip Rideout
6047d3235f Remove VSM variant from Skybox material. 2020-12-14 11:19:31 -08:00
Philip Rideout
2cda6e35bd math: reduce template bloat for matrices
This does not change our API, it merely reduces the number of
non-inlined function instantiations appearing in non-optimized binaries.
2020-12-14 11:19:22 -08:00
Philip Rideout
8f8d51e17b Code review fixups for libibl_lite. 2020-12-14 11:19:16 -08:00
Philip Rideout
6919e3b274 libibl: use C callback for progress 2020-12-14 11:19:09 -08:00
Philip Rideout
10bf944410 Add libibl_lite. 2020-12-14 11:19:03 -08:00
Philip Rideout
9a2f6fdb53 Vulkan: change vkWaitForFences usage for SwiftShader.
When passing only 1 fence to vkWaitForFences, the `waitAll` argument
should not have any effect, but SwiftShader seems to skip the wait
when this argument is set to VK_FALSE.

More specifically, the failure to wait in `acquireWorkCommandBuffer`
causes the subsequent destruction of an in-use fence, which causes
a TSAN failure with Google's internal tests.

I am consulting with the SwiftShader team on a real fix, meanwhile
we can commit this easy workaround.

We have 5 usages of vkWaitForFences, one of which uses multiple fences
and should have used VK_TRUE anyway.
2020-11-20 09:37:54 -08:00
Philip Rideout
761977d385 Filament should always bind an IBL texture.
This prevents a SwiftShader crash and/or a slew of "no texture bound"
warnings that would appear when the client provides an IBL without
providing reflections texture, which should be a valid thing to do.

Note that it is okay to declare a sampler in GLSL that never gets bound,
as long as it is never sampled from. Since we always sample from the
IBL specular texture, we should always bind something to it.
2020-11-19 13:28:19 -08:00
Ben Doherty
21248f15b5 Fix, matc crash when building mobile materials (#3296) 2020-11-16 14:37:55 -08:00
Benjamin Doherty
4f32817f6d Bump version to 1.9.10 2020-11-16 12:37:49 -08:00
Benjamin Doherty
cc9e05e711 Merge branch 'rc/1.9.9' into release 2020-11-16 12:34:13 -08:00
Benjamin Doherty
419d68d4db Update RELEASE_NOTES for 1.9.9 2020-11-16 12:17:02 -08:00
Philip Rideout
8450232448 Improve the "unbound texture" warnings.
With Vulkan, this warning would sometimes be a false positive. It could
trigger for internal samplers like `ssao` and `structure`, even though
they were not declared in SPIR-V.

With OpenGL, this warning would never be a false positive because it has
the luxury of calling `glGetUniformLocation`.

This adds a private attribute to our samplers called `strict` that
indicates whether or not a sampler should always have a bound texture.
For now the only strict samplers are the custom ones declared in the
user's material.

At some point I think we should consider adding `spirv-reflect` to our
tree to help with problems like this.
2020-11-12 16:21:13 -08:00
Philip Rideout
cc51726590 Vulkan: improve robustness by providing 1x1 fallback. 2020-11-12 10:36:13 -08:00
Philip Rideout
318e22af51 Fix clear behavior with RenderTarget API.
This fixes a bug seen with client applications that use ClearOptions
instead of Skybox, and one or more offscreen RenderTarget objects.
These apps would see junk pixels because Filament would only clear the
first render target in the frame.

The fix is to factor some the flag-setting logic in `beginFrame()` into
a private method, and call this method from `render()` each time
the user-level RenderTarget has been changed.

I wrote a simple C++ demo to reproduce the issue and to verify that
this fix works.
2020-11-11 09:25:36 -08:00
Philip Rideout
68ac87dc24 NOOP backend should not care about GLSL vs SPIRV.
This fixes errors that would occur when using the NOOP backend with
materials that were built without OpenGL support.
2020-11-10 15:44:01 -08:00
Benjamin Doherty
acb8f00075 Bump version to 1.9.9 2020-11-09 09:32:55 -08:00
Benjamin Doherty
06d9183aaa Merge branch 'rc/1.9.8' into release 2020-11-09 09:28:58 -08:00
Benjamin Doherty
75af25419d Update RELEASE_NOTES for 1.9.8 2020-11-09 09:26:27 -08:00
Benjamin Doherty
f6b90d2a31 Bump version to 1.9.8 2020-11-09 09:21:36 -08:00
Philip Rideout
a3822f4af0 Fix FENCE_WAIT_FOR_EVER in Linux.
The number of infinite nanoseconds was negative because we asked
chrono for a signed integer, so "wait forever" really meant "do not
wait at all".
2020-11-02 16:12:53 -08:00
Benjamin Doherty
bcdad769ff Merge branch 'rc/1.9.7' into release 2020-11-02 11:03:57 -07:00
Benjamin Doherty
be4fb4fdbb Update RELEASE_NOTES for 1.9.7 2020-11-02 10:59:19 -07:00
Benjamin Doherty
65394f6301 Bump version to 1.9.7 2020-10-26 11:34:20 -06:00
Benjamin Doherty
b0beee03bc Merge branch 'rc/1.9.6' into release 2020-10-26 11:29:45 -06:00
Benjamin Doherty
fe1de41b8e Update RELEASE_NOTES for 1.9.6 2020-10-26 11:25:31 -06:00
Benjamin Doherty
a37b431e87 Bump version to 1.9.6 2020-10-19 11:55:13 -06:00
Benjamin Doherty
98107016b9 Merge branch 'rc/1.9.5' into release 2020-10-19 11:51:30 -06:00
Benjamin Doherty
8bccfc2863 Update RELEASE_NOTES for 1.9.5 2020-10-19 11:49:05 -06:00
Benjamin Doherty
f54a0a3452 Fix CocoaPod version 2020-10-13 15:15:02 -06:00
Benjamin Doherty
6778ab0624 Fix CocoaPod version 2020-10-13 15:09:59 -06:00
Benjamin Doherty
269d636785 Bump version to 1.9.5 2020-10-12 12:03:29 -06:00
Benjamin Doherty
39862c91ce Merge branch 'rc/1.9.4' into release 2020-10-12 11:56:24 -06:00
Benjamin Doherty
523f4026b4 Update RELEASE_NOTES for 1.9.4 2020-10-12 11:52:01 -06:00
Benjamin Doherty
a6bf162431 Bump version to 1.9.4 2020-10-07 16:06:23 -06:00
Benjamin Doherty
826e8d181c Merge branch 'rc/1.9.3' into release 2020-10-05 11:36:16 -06:00
Benjamin Doherty
16dfadbba0 Update RELEASE_NOTES for 1.9.3 2020-10-05 11:29:36 -06:00
Benjamin Doherty
5cbb97551f Bump version to 1.9.3 2020-09-28 11:40:31 -06:00
Benjamin Doherty
defee767c3 Merge branch 'rc/1.9.2' into release 2020-09-28 11:27:47 -06:00
Benjamin Doherty
9560318521 Update RELEASE_NOTES for 1.9.2 2020-09-28 11:26:21 -06:00
Benjamin Doherty
ef09feb048 Bump version to 1.9.2 2020-09-21 11:16:53 -06:00
Benjamin Doherty
39f323fe09 Merge branch 'rc/1.9.1' into release 2020-09-21 11:00:07 -06:00
Benjamin Doherty
11b95304ea Merge branch 'release' into rc/1.9.1 2020-09-21 10:59:52 -06:00
Benjamin Doherty
b7c30a7916 Update RELEASE_NOTES for 1.9.1 2020-09-21 10:59:06 -06:00
Benjamin Doherty
4cae48fc77 Bump version to 1.9.1 2020-09-14 11:51:36 -07:00
Benjamin Doherty
d1a93f0557 Update release notes for 1.9.0 2020-09-14 10:54:28 -07:00
Benjamin Doherty
b93059fad7 Bump version to 1.9.0 2020-09-08 10:47:23 -07:00
914 changed files with 87606 additions and 28546 deletions

View File

@@ -27,17 +27,24 @@ runs:
echo "$HASH" > /tmp/commit_hash.txt
- name: Find commit message (PR)
shell: bash
id: checkout_code
if: github.event_name == 'pull_request'
run: |
BEFORE_HASH=$(git rev-parse HEAD)
echo "hash=$BEFORE_HASH" >> "$GITHUB_OUTPUT"
# Next we will checkout the actual head (not the merge commits) of the PR
AFTER_HASH="${{ github.event.pull_request.head.sha }}"
git checkout $AFTER_HASH
COMMIT_MESSAGE=$(git log -1 --no-merges)
echo "$COMMIT_MESSAGE" > /tmp/commit_msg.txt
echo "$AFTER_HASH" > /tmp/commit_hash.txt
PR_NUMBER="${{ github.event.pull_request.number }}"
# Fetch the head of the PR explicitly to handle forks. Depth 50 ensures we can traverse past recent merge commits.
git fetch --depth=50 origin "pull/$PR_NUMBER/head:pr-head"
COMMIT_HASH=$(git log -1 --no-merges pr-head --format=%H)
AUTHOR_NAME=$(git log -1 --no-merges pr-head --format=%an)
AUTHOR_EMAIL=$(git log -1 --no-merges pr-head --format=%ae)
TSTAMP=$(git log -1 --no-merges pr-head --format=%aI)
COMMIT_MESSAGE=$(git log -1 --no-merges pr-head --format=%B)
echo "commit $COMMIT_HASH" > /tmp/commit_msg.txt
echo "Author: ${AUTHOR_NAME}<${AUTHOR_EMAIL}>" >> /tmp/commit_msg.txt
echo "Date: ${TSTAMP}" >> /tmp/commit_msg.txt
echo "" >> /tmp/commit_msg.txt
echo "$COMMIT_MESSAGE" >> /tmp/commit_msg.txt
echo "$COMMIT_HASH" > /tmp/commit_hash.txt
- shell: bash
id: action_output
run: |
@@ -47,9 +54,4 @@ runs:
cat /tmp/commit_msg.txt >> "$GITHUB_OUTPUT"
echo "$DELIMITER" >> "$GITHUB_OUTPUT"
# Get the commit hash
echo "hash=$(cat /tmp/commit_hash.txt)" >> "$GITHUB_OUTPUT"
- name: Cleanup Find commit message (PR)
shell: bash
if: github.event_name == 'pull_request'
run: |
git checkout ${{ steps.checkout_code.outputs.hash }}
echo "hash=$(cat /tmp/commit_hash.txt)" >> "$GITHUB_OUTPUT"

View File

@@ -15,7 +15,7 @@ runs:
uses: actions/cache@v4 # Use a specific version
with:
path: ~/Library/Caches/Homebrew
key: ${{ runner.os }}-brew-20250424
key: ${{ runner.os }}-brew-20251211
- name: Install Mac Prerequisites
shell: bash
run: |

View File

@@ -0,0 +1,26 @@
name: 'Renderdiff Generate'
description: 'Sets up prerequisites and runs the generate script for renderdiff'
runs:
using: "composite"
steps:
- uses: ./.github/actions/mac-prereq
- uses: ./.github/actions/get-gltf-assets
- uses: ./.github/actions/get-mesa
- uses: ./.github/actions/get-vulkan-sdk
- name: Prerequisites
run: |
# Must have at least clang-16 for a webgpu/dawn build.
sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer
shell: bash
- name: Generate images
run: |
TEST_DIR=test/renderdiff
source ${TEST_DIR}/src/preamble.sh
set -eux
bash ${TEST_DIR}/generate.sh
set +eux
shell: bash
- name: Build diffimg tool
run: |
./build.sh release diffimg
shell: bash

View File

@@ -1,25 +0,0 @@
name: Android
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-android:
name: build-android
# We intentially use a larger runner here to enable larger disk space
# (standard linux runner will fail on disk space and faster build time).
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- name: Run Android Continuous
uses: ./.github/actions/android-continuous
with:
build-abi: armeabi-v7a,arm64-v8a,x86_64

View File

@@ -1,29 +0,0 @@
name: iOS
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-ios:
name: build-ios
runs-on: macos-14-xlarge
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/mac-prereq
- name: Run build script
run: |
cd build/ios && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-ios
path: out/filament-release-ios.tgz
- name: Build iOS samples
run: |
cd build/ios && ./build-samples.sh continuous

View File

@@ -1,26 +0,0 @@
name: Linux
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-linux:
name: build-linux
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- name: Run build script
run: |
cd build/linux && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-linux
path: out/filament-release-linux.tgz

View File

@@ -1,29 +0,0 @@
name: macOS
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-mac:
name: build-mac
runs-on: macos-14-xlarge
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/mac-prereq
- name: Run build script
run: |
cd build/mac && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-mac
path: out/filament-release-darwin.tgz
- name: Check public headers
run: |
test/check-headers/test.sh out/release/filament/include

124
.github/workflows/postsubmit-main.yml vendored Normal file
View File

@@ -0,0 +1,124 @@
name: 'Postsubmit Tasks'
on:
push:
branches:
- main
jobs:
# Update the renderdiff goldens in filament-assets. This will add or merge the new goldens from
# a branch on filament-assets.
update-renderdiff-goldens:
name: update-renderdiff-goldens
runs-on: 'macos-14-xlarge'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- id: get_commit_msg
uses: ./.github/actions/get-commit-msg
- name: Check if accepting new goldens
id: check_accept
env:
COMMIT_MESSAGE: ${{ steps.get_commit_msg.outputs.msg }}
run: |
if echo "${COMMIT_MESSAGE}" | python3 test/renderdiff/src/commit_msg.py --mode=accept_new_goldens; then
echo "accept=true" >> "$GITHUB_OUTPUT"
else
echo "accept=false" >> "$GITHUB_OUTPUT"
fi
shell: bash
- name: Renderdiff Generate for new goldens
if: steps.check_accept.outputs.accept == 'true'
uses: ./.github/actions/renderdiff-generate
- name: Run update script
env:
GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }}
COMMIT_MESSAGE: ${{ steps.get_commit_msg.outputs.msg }}
run: |
GOLDEN_BRANCH=$(echo "${COMMIT_MESSAGE}" | python3 test/renderdiff/src/commit_msg.py)
COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}"
git config --global user.email "filament.bot@gmail.com"
git config --global user.name "Filament Bot"
git config --global credential.helper cache
if [[ "${{ steps.check_accept.outputs.accept }}" == "true" ]]; then
SHORT_HASH="${COMMIT_HASH:0:8}"
GOLDEN_BRANCH="accept-goldens-${SHORT_HASH}"
echo "Generating new goldens for branch ${GOLDEN_BRANCH}"
python3 test/renderdiff/src/update_golden.py \
--branch=${GOLDEN_BRANCH} \
--source=$(pwd)/out/renderdiff/renders \
--commit-msg="Auto-update goldens from ${COMMIT_HASH}" \
--push-to-remote \
--golden-repo-token=${GH_TOKEN}
fi
if [[ "${GOLDEN_BRANCH}" != "main" ]]; then
echo "branch==${GOLDEN_BRANCH}"
echo "hash==${COMMIT_HASH}"
python3 test/renderdiff/src/update_golden.py --branch=${GOLDEN_BRANCH} \
--merge-to-main --filament-tag=${COMMIT_HASH} --golden-repo-token=${GH_TOKEN}
fi
# Update the /docs (offiicla github-hosted Filament site) if necessary
update-docs:
name: update-docs
runs-on: 'ubuntu-24.04-4core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- id: get_commit_msg
uses: ./.github/actions/get-commit-msg
- name: Prerequisites
run: pip install selenium
- name: Run update script
env:
GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }}
run: |
bash docs_src/build/install_mdbook.sh && source ~/.bashrc
COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}"
git config --global user.email "filament.bot@gmail.com"
git config --global user.name "Filament Bot"
git config --global credential.helper cache
bash docs_src/build/postsubmit.sh ${COMMIT_HASH} ${GH_TOKEN}
# Produce a json that describes the android artifact sizes, and will push that json to a folder in
# filament-assets
update-sizeguard:
name: update-sizeguard
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- id: get_commit_msg
uses: ./.github/actions/get-commit-msg
- name: Build and generate size report
run: |
cd build/android && printf "y" | ./build.sh release all
cd ../..
COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}"
python3 test/sizeguard/dump_artifact_size.py out/*.tgz out/*.aar > "${COMMIT_HASH}.json"
- name: Push to filament-assets
env:
GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }}
run: |
COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}"
git config --global user.email "filament.bot@gmail.com"
git config --global user.name "Filament Bot"
git clone https://x-access-token:${GH_TOKEN}@github.com/google/filament-assets.git filament-assets
mkdir -p filament-assets/sizeguard
mv "${COMMIT_HASH}.json" filament-assets/sizeguard/
cd filament-assets
git add sizeguard/"${COMMIT_HASH}.json"
git commit -m "Update sizeguard for filament@${COMMIT_HASH}" || echo "No changes to commit"
git push https://x-access-token:${GH_TOKEN}@github.com/google/filament-assets.git main

View File

@@ -1,58 +1,115 @@
name: 'Post-submit tasks'
name: 'Postsubmit CI'
on:
push:
branches:
- main
- release
- rc/**
jobs:
update-renderdiff-goldens:
name: update-renderdiff-goldens
runs-on: 'ubuntu-24.04-4core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- id: get_commit_msg
uses: ./.github/actions/get-commit-msg
- name: Prerequisites
run: pip install tifffile numpy
- name: Run update script
env:
GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }}
run: |
GOLDEN_BRANCH=$(echo "${{ steps.get_commit_msg.outputs.msg }}" | python3 test/renderdiff/src/commit_msg.py)
COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}"
if [[ "${GOLDEN_BRANCH}" != "main" ]]; then
git config --global user.email "filament.bot@gmail.com"
git config --global user.name "Filament Bot"
git config --global credential.helper cache
echo "branch==${GOLDEN_BRANCH}"
echo "hash==${COMMIT_HASH}"
python3 test/renderdiff/src/update_golden.py --branch=${GOLDEN_BRANCH} \
--merge-to-main --filament-tag=${COMMIT_HASH} --golden-repo-token=${GH_TOKEN}
fi
build-android:
name: build-android
# We intentially use a larger runner here to enable larger disk space
# (standard linux runner will fail on disk space and faster build time).
runs-on: 'ubuntu-24.04-16core'
update-docs:
name: update-docs
runs-on: 'ubuntu-24.04-4core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- id: get_commit_msg
uses: ./.github/actions/get-commit-msg
- name: Prerequisites
run: pip install selenium
- name: Run update script
env:
GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }}
- name: Run Android Continuous
uses: ./.github/actions/android-continuous
with:
build-abi: armeabi-v7a,arm64-v8a,x86_64
build-ios:
name: build-ios
runs-on: macos-14-xlarge
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/mac-prereq
- name: Run build script
run: |
bash docs_src/build/install_mdbook.sh && source ~/.bashrc
COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}"
git config --global user.email "filament.bot@gmail.com"
git config --global user.name "Filament Bot"
git config --global credential.helper cache
bash docs_src/build/postsubmit.sh ${COMMIT_HASH} ${GH_TOKEN}
cd build/ios && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-ios
path: out/filament-release-ios.tgz
- name: Build iOS samples
run: |
cd build/ios && ./build-samples.sh continuous
build-linux:
name: build-linux
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- name: Run build script
run: |
cd build/linux && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-linux
path: out/filament-release-linux.tgz
build-mac:
name: build-mac
runs-on: macos-14-xlarge
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/mac-prereq
- name: Run build script
run: |
cd build/mac && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-mac
path: out/filament-release-darwin.tgz
- name: Check public headers
run: |
test/check-headers/test.sh out/release/filament/include
build-web:
name: build-web
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- uses: ./.github/actions/web-prereq
- name: Run build script
run: |
cd build/web && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-web
path: out/filament-release-web.tgz
build-windows:
name: build-windows
runs-on: windows-2022-32core
steps:
- uses: actions/checkout@v4.1.6
- name: Run build script
run: |
build\windows\build-github.bat continuous
shell: cmd
- uses: actions/upload-artifact@v4
with:
name: filament-windows
path: out/filament-windows.tgz

View File

@@ -1,4 +1,4 @@
name: Presubmit
name: 'Presubmit CI'
on:
push:
@@ -19,7 +19,7 @@ jobs:
- uses: ./.github/actions/mac-prereq
- name: Run build script
run: |
cd build/mac && printf "y" | ./build.sh presubmit
cd build/mac && printf "y" | ./build.sh presubmit-with-test
- name: Test material parser
run: |
out/cmake-release/filament/test/test_material_parser
@@ -67,7 +67,16 @@ jobs:
# Only build 1 64 bit target during presubmit to cut down build times during presubmit
# Continuous builds will build everything
run: |
cd build/android && printf "y" | ./build.sh presubmit arm64-v8a
pushd .
cd build/android && printf "y" | ./build.sh presubmit-with-archive arm64-v8a
popd
- name: Check artifact sizes
run: |
python3 test/sizeguard/dump_artifact_size.py out/*.aar > current_size.json
python3 test/sizeguard/check_size.py current_size.json \
--target-branch origin/main \
--threshold 20480 \
--artifacts filament-android-release.aar/jni/arm64-v8a/libfilament-jni.so
build-ios:
name: build-iOS
@@ -117,40 +126,46 @@ jobs:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/mac-prereq
- uses: ./.github/actions/get-gltf-assets
- uses: ./.github/actions/get-mesa
- uses: ./.github/actions/get-vulkan-sdk
- id: get_commit_msg
uses: ./.github/actions/get-commit-msg
- name: Prerequisites
- name: Check if accepting new goldens
id: check_accept
env:
COMMIT_MESSAGE: ${{ steps.get_commit_msg.outputs.msg }}
run: |
pip install tifffile numpy
# Must have at least clang-16 for a webgpu/dawn build.
sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer
if echo "${COMMIT_MESSAGE}" | python3 test/renderdiff/src/commit_msg.py --mode=accept_new_goldens; then
echo "accept=true" >> "$GITHUB_OUTPUT"
else
echo "accept=false" >> "$GITHUB_OUTPUT"
fi
shell: bash
- name: Renderdiff Generate
if: steps.check_accept.outputs.accept != 'true'
uses: ./.github/actions/renderdiff-generate
- name: Render and compare
if: steps.check_accept.outputs.accept != 'true'
id: render_compare
env:
COMMIT_MESSAGE: ${{ steps.get_commit_msg.outputs.msg }}
run: |
ls ./gltf/Models
TEST_DIR=test/renderdiff
source ${TEST_DIR}/src/preamble.sh
start_
set -eux
GOLDEN_BRANCH=$(echo "${COMMIT_MESSAGE}" | python3 ${TEST_DIR}/src/commit_msg.py)
bash ${TEST_DIR}/generate.sh && \
python3 ${TEST_DIR}/src/golden_manager.py \
python3 ${TEST_DIR}/src/golden_manager.py \
--branch=${GOLDEN_BRANCH} \
--output=${GOLDEN_OUTPUT_DIR}
# Note that we need to upload the output even if comparison fails, so we undo `set -ex`
end_
# Note that we need to upload the output even if comparison fails, so we undo `set -eux`
set +eux
python3 ${TEST_DIR}/src/compare.py \
--src=${GOLDEN_OUTPUT_DIR} \
--dest=${RENDER_OUTPUT_DIR} \
--out=${DIFF_OUTPUT_DIR} 2>&1 | tee compare_output.txt
--out=${DIFF_OUTPUT_DIR} \
--diffimg="$(pwd)/out/cmake-release/tools/diffimg/diffimg" \
--test="${TEST_DIR}/tests/presubmit.json" 2>&1 | tee compare_output.txt
if grep "Failed" compare_output.txt > /dev/null; then
DELIMITER="EOF_FILE_CONTENT_$(date +%s)" # Using timestamp to make it more unique
@@ -158,11 +173,14 @@ jobs:
cat compare_output.txt >> "$GITHUB_OUTPUT"
echo "$DELIMITER" >> "$GITHUB_OUTPUT"
fi
shell: bash
- uses: actions/upload-artifact@v4
if: steps.check_accept.outputs.accept != 'true'
with:
name: presubmit-renderdiff-result
path: ./out/renderdiff
- name: Compare result
if: steps.check_accept.outputs.accept != 'true'
run: |
ERROR_STR="${{ steps.render_compare.outputs.err }}"
if [ -n "${ERROR_STR}" ]; then

View File

@@ -163,9 +163,7 @@ jobs:
mv out/filamat-android-release.aar out/filamat-${TAG}-android.aar
mv out/gltfio-android-release.aar out/gltfio-${TAG}-android.aar
mv out/filament-utils-android-release.aar out/filament-utils-${TAG}-android.aar
cd out/android-release/filament
tar -czf ../../filament-${TAG}-android-native.tgz .
cd ../../..
mv out/filament-android-release-linux.tgz out/filament-${TAG}-android-native.tgz
- name: Sign sample-gltf-viewer
run: |
echo "${APK_KEYSTORE_BASE64}" > filament.jks.base64
@@ -190,6 +188,54 @@ jobs:
const globber = await glob.create(['out/*.aar', 'out/*.apk', 'out/*.tgz'].join('\n'));
await upload({ github, context }, await globber.glob(), TAG);
sonatype-publish:
name: sonatype-publish
runs-on: 'ubuntu-24.04-16core'
# Depends on the the Android build for the Android binaries.
# Depends on the Mac, Linux, and Windows builds for host tools.
needs: [build-mac, build-linux, build-windows, build-android]
if: github.event_name == 'release' || github.event.inputs.platform == 'android'
steps:
- name: Decide Git ref
id: git_ref
run: |
REF=${RELEASE_TAG:-${GITHUB_REF}}
TAG=${REF##*/}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v4.1.6
with:
ref: ${{ steps.git_ref.outputs.ref }}
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- uses: ./.github/actions/linux-prereq
- name: Download Android Release
run: |
gh release download ${TAG} \
--repo ${{ github.repository }} \
--pattern 'filament-*-android-native.tgz'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ steps.git_ref.outputs.tag }}
- name: Unzip Android Release
run: |
mkdir -p out/android-release
tar -xzvf filament-${TAG}-android-native.tgz -C out/android-release/
env:
TAG: ${{ steps.git_ref.outputs.tag }}
- name: Publish To Sonatype
run: |
cd android
./gradlew publishToSonatype closeSonatypeStagingRepository
env:
ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }}
ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }}
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.MAVEN_SIGNING_KEY }}
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.MAVEN_SIGNING_PASSWORD }}
build-ios:
name: build-ios
runs-on: macos-14-xlarge
@@ -245,7 +291,8 @@ jobs:
env:
TAG: ${{ steps.git_ref.outputs.tag }}
run: |
build\windows\build-github.bat release
@REMARK 'call' is required to ensure control returns to this script after the batch file finishes.
call build\windows\build-github.bat release
echo on
move out\filament-windows.tgz out\filament-%TAG%-windows.tgz
shell: cmd

View File

@@ -1,27 +0,0 @@
name: Web
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-web:
name: build-web
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- uses: ./.github/actions/web-prereq
- name: Run build script
run: |
cd build/web && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-web
path: out/filament-release-web.tgz

View File

@@ -1,24 +0,0 @@
name: Windows
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-windows:
name: build-windows
runs-on: windows-2022-32core
steps:
- uses: actions/checkout@v4.1.6
- name: Run build script
run: |
build\windows\build-github.bat continuous
shell: cmd
- uses: actions/upload-artifact@v4
with:
name: filament-windows
path: out/filament-windows.tgz

View File

@@ -1,6 +1,6 @@
## Building Filament
# Building Filament
### Prerequisites
## Prerequisites
To build Filament, you must first install the following tools:
@@ -18,7 +18,7 @@ To build Filament for Android you must also install the following:
- Android NDK 25.1 or higher
- Java 17
### Environment variables
## Environment variables
To build Filament for Android, make sure the environment variable `ANDROID_HOME` points to the
location of your Android SDK.
@@ -30,7 +30,7 @@ When building for WebGL, you'll also need to set `EMSDK`. See [WebAssembly](#web
We recommend using CLion to develop for Filament. Simply open the root directory's CMakeLists.txt
in CLion to obtain a usable project.
### Easy build
## Easy build
Once the required OS specific dependencies listed below are installed, you can use the script
located in `build.sh` to build Filament easily on macOS and Linux.
@@ -67,7 +67,7 @@ For more specialized options, please also consider the following pages:
- `-t`: [`fgviewer`](https://google.github.io/filament/dup/fgviewer.html)
- `-b` and `-y`: [ASAN/UBSAN builds](https://google.github.io/filament/notes/asan_ubsan.html)
### Filament-specific CMake Options
## Filament-specific CMake Options
The following CMake options are boolean options specific to Filament:
@@ -89,7 +89,7 @@ cmake . -DOPTION=ON # Replace OPTION with the option name, set to ON / OFF
Options can also be set with the CMake GUI.
### Linux
## Linux
Make sure you've installed the following dependencies:
@@ -148,7 +148,7 @@ ninja
This will build Filament, its tests and samples, and various host tools.
### macOS
## macOS
To compile Filament you must have the most recent version of Xcode installed and you need to
make sure the command line tools are setup by running:
@@ -169,7 +169,7 @@ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/fila
ninja
```
### iOS
## iOS
The easiest way to build Filament for iOS is to use `build.sh` and the
`-p ios` flag. For instance to build the debug target:
@@ -180,9 +180,9 @@ The easiest way to build Filament for iOS is to use `build.sh` and the
See [ios/samples/README.md](./ios/samples/README.md) for more information.
### Windows
## Windows
#### Building on Windows with Visual Studio 2019 or later
### Building on Windows with Visual Studio 2019 or later
Install the following components:
@@ -225,7 +225,7 @@ You can also use CMake to invoke the build without opening Visual Studio. For ex
cmake --build . --target gltf_viewer --config Release
```
### Android
## Android
Before building Filament for Android, make sure to build Filament for your host. Some of the
host tools are required to successfully build for Android.
@@ -242,7 +242,13 @@ foremost for `arm64-v8a`.
To build Android on Windows machines, see [android/Windows.md](android/Windows.md).
#### Easy Android build
### Important: SDK location
Either ensure your `ANDROID_HOME` environment variable is set or make sure the root project
contains a `local.properties` file with the `sdk.dir` property pointing to your installation of
the Android SDK.
### Easy Android build
The easiest way to build Filament for Android is to use `build.sh` and the
`-p android` flag. For instance to build the release target:
@@ -251,9 +257,46 @@ The easiest way to build Filament for Android is to use `build.sh` and the
./build.sh -p android release
```
To build a sample (such as `android/samples/sample-hello-triangle`) for an ARM 64-bit phone, you would run
```shell
./build.sh -p android -q arm64-v8a -k sample-hello-triangle release
```
The output APK can be found in `android/samples/sample-hello-triangle/build/outputs/apk/release/sample-hello-triangle-release-unsigned.apk`
Run `build.sh -h` for more information.
#### Manual builds
### Android Studio
You must use the latest stable release of Android Studio.
The Android build of filament is separated into java/kotlin client APIs, a layer of jni bindings
that bridges java/kotlin with native code, and Filament and other component code that have been compiled
into architecture-specific libraries. Our default Android Studio gradle setup can compile java/kotlin and
the jni bindings for you, but it will treat the filament libraries as already compiled and present on
the system.
Therefore, before compiling the sample app or any other targets, you must
make sure that the native filament libraries have been compiled and are located at a prescribed location
so that the jni bindings can link against them. You can do so by using the easy build script
```shell
./build.sh -p android release -q arm64-v8a
```
Note that the above step will also install host machine tools into prescribed locations. These tools are
required for compiling Filament assets such as materials and environment maps.
Now we are ready to compile the apps. To open the project, point Studio to the `android` folder.
After opening the project and syncing with Gradle, select the sample of your choice
using the drop-down widget in the toolbar. Additionally, you will need to select a deployment target.
By doing so, Android Studio will automatically try to compile the app only for that specific
device's architecture. So if you are targeting a new Pixel phone, make sure that the step above
(compiling the library) is targeting ARM 64-bit (`-q arm64-v8a` ), and if you are running the app on
an emulator on a Linux machine with an x86 64-bit chipset, you would indicate (`-q x86_64`) in the above step.
### Manual builds
Invoke CMake in a build directory of your choice, inside of filament's directory. The commands
below show how to build Filament for ARM 64-bit (`aarch64`).
@@ -281,7 +324,7 @@ This will generate Filament's Android binaries in `out/android-release`. This lo
to build the Android Studio projects located in `filament/android`. After install, the library
binaries should be found in `out/android-release/filament/lib/arm64-v8a`.
#### AAR
### AAR
Before you attempt to build the AAR, make sure you've compiled and installed the native libraries
as explained in the sections above. You must have the following ABIs built in
@@ -313,7 +356,7 @@ Alternatively you can build the AAR from the command line by executing the follo
The `-Pcom.google.android.filament.dist-dir` can be used to specify a different installation
directory (it must match the CMake install prefix used in the previous steps).
#### Using Filament's AAR
### Using Filament's AAR
Create a new module in your project and select _Import .JAR or .AAR Package_ when prompted. Make
sure to add the newly created module as a dependency to your application.
@@ -354,7 +397,7 @@ productFlavors {
}
```
### WebAssembly
## WebAssembly
The core Filament library can be cross-compiled to WebAssembly from either macOS or Linux. To get
started, follow the instructions for building Filament on your platform ([macOS](#macos) or

View File

@@ -10,6 +10,7 @@ cmake_minimum_required(VERSION 3.22.1)
# ==================================================================================================
# Toolchain configuration
# ==================================================================================================
# On iOS, the deployment target is set inside third_party/clang/ios.cmake
if (APPLE AND NOT IOS)
# This must be set before project() is called
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15 CACHE STRING "")
@@ -64,6 +65,8 @@ option(FILAMENT_SUPPORTS_WEBP_TEXTURES "Enable webp texture support for Filament
# On the regular filament build (where size is of less concern), we enable GTAO by default.
option(FILAMENT_DISABLE_GTAO "Disable GTAO" OFF)
option(FILAMENT_BUILD_TESTING "Build tests" ON)
set(FILAMENT_NDK_VERSION "" CACHE STRING
"Android NDK version or version prefix to be used when building for Android."
)
@@ -367,14 +370,22 @@ endif()
if (LINUX)
option(USE_STATIC_LIBCXX "Link against the static runtime libraries." ON)
# Add this step to support both glibc-based Linux distributions (e.g., Ubuntu, Debian)
# and musl-based distributions (e.g., Alpine).
include(CheckSymbolExists)
check_symbol_exists(__GLIBC__ "features.h" CLANG_WITH_GLIBC)
if (${USE_STATIC_LIBCXX})
if (FILAMENT_USING_GCC)
link_libraries("-static-libgcc -static-libstdc++")
else ()
elseif (CLANG_WITH_GLIBC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
link_libraries("-static-libgcc -static-libstdc++")
link_libraries(libc++.a)
link_libraries(libc++abi.a)
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static")
endif()
endif()
@@ -473,7 +484,7 @@ endif()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${EXTRA_SANITIZE_OPTIONS}")
if (FILAMENT_ENABLE_COVERAGE)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping -Wno-pass-failed")
endif()
# Disable the stack check for macOS to workaround a known issue in clang 11.0.0.
@@ -563,6 +574,10 @@ if (FILAMENT_SUPPORTS_WEBGPU)
add_definitions(-DFILAMENT_SUPPORTS_WEBGPU)
endif()
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
add_definitions(-DFILAMENT_SUPPORTS_WEBP_TEXTURES)
endif()
# Build with Metal support on non-WebGL Apple platforms.
if (APPLE AND NOT WEBGL)
option(FILAMENT_SUPPORTS_METAL "Include the Metal backend" ON)
@@ -574,7 +589,7 @@ if (FILAMENT_SUPPORTS_METAL)
endif()
# Building filamat increases build times and isn't required for web, so turn it off by default.
if (NOT WEBGL AND NOT IOS)
if (NOT WEBGL)
option(FILAMENT_BUILD_FILAMAT "Build filamat and JNI buildings" ON)
else()
option(FILAMENT_BUILD_FILAMAT "Build filamat and JNI buildings" OFF)
@@ -864,6 +879,7 @@ add_subdirectory(${LIBRARIES}/gltfio)
add_subdirectory(${LIBRARIES}/ibl)
add_subdirectory(${LIBRARIES}/iblprefilter)
add_subdirectory(${LIBRARIES}/image)
add_subdirectory(${LIBRARIES}/imagediff)
add_subdirectory(${LIBRARIES}/ktxreader)
add_subdirectory(${LIBRARIES}/math)
add_subdirectory(${LIBRARIES}/mathio)
@@ -872,7 +888,9 @@ add_subdirectory(${LIBRARIES}/utils)
add_subdirectory(${LIBRARIES}/viewer)
add_subdirectory(${FILAMENT}/shaders)
add_subdirectory(${EXTERNAL}/abseil/tnt)
add_subdirectory(${EXTERNAL}/basisu/tnt)
# Add zstd before basisu to force it to use the external zstd target,
# preventing a duplicate symbol conflict with its bundled version.
add_subdirectory(${EXTERNAL}/zstd/tnt)
add_subdirectory(${EXTERNAL}/civetweb/tnt)
add_subdirectory(${EXTERNAL}/imgui/tnt)
add_subdirectory(${EXTERNAL}/robin-map/tnt)
@@ -886,8 +904,10 @@ add_subdirectory(${EXTERNAL}/jsmn/tnt)
add_subdirectory(${EXTERNAL}/stb/tnt)
add_subdirectory(${EXTERNAL}/getopt)
add_subdirectory(${EXTERNAL}/perfetto/tnt)
add_subdirectory(${EXTERNAL}/zstd/tnt)
add_subdirectory(${EXTERNAL}/basisu/tnt)
# imageio-lite is needed for viewer
add_subdirectory(${LIBRARIES}/imageio-lite)
# Note that this has to be placed after mikktspace in order for combine_static_libs to work.
add_subdirectory(${LIBRARIES}/geometry)
@@ -913,7 +933,6 @@ endif()
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
add_subdirectory(${EXTERNAL}/libwebp/tnt)
add_definitions(-DFILAMENT_SUPPORTS_WEBP_TEXTURES)
endif()
if (FILAMENT_SUPPORTS_VULKAN)
@@ -957,6 +976,7 @@ if (IS_HOST_PLATFORM)
add_subdirectory(${TOOLS}/cmgen)
add_subdirectory(${TOOLS}/cso-lut)
add_subdirectory(${TOOLS}/diffimg)
add_subdirectory(${TOOLS}/filamesh)
add_subdirectory(${TOOLS}/glslminifier)
add_subdirectory(${TOOLS}/matc)
@@ -971,6 +991,7 @@ if (IS_HOST_PLATFORM)
add_subdirectory(${TOOLS}/roughness-prefilter)
add_subdirectory(${TOOLS}/specular-color)
add_subdirectory(${TOOLS}/uberz)
add_subdirectory(${TOOLS}/specgen)
endif()
# Generate exported executables for cross-compiled builds (Android, WebGL, and iOS)

View File

@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.67.1'
implementation 'com.google.android.filament:filament-android:1.70.1'
}
```
@@ -39,19 +39,18 @@ Here are all the libraries available in the group `com.google.android.filament`:
| Artifact | Description |
| ------------- | ------------- |
| [![filament-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android/badge.svg?subject=filament-android)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android) | The Filament rendering engine itself. |
| [![filament-android-debug](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android-debug/badge.svg?subject=filament-android-debug)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android-debug) | Debug version of `filament-android`. |
| [![gltfio-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android/badge.svg?subject=gltfio-android)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android) | A glTF 2.0 loader for Filament, depends on `filament-android`. |
| [![filament-utils-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android/badge.svg?subject=filament-utils-android)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android) | KTX loading, Kotlin math, and camera utilities, depends on `gltfio-android`. |
| [![filamat-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android/badge.svg?subject=filamat-android)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android) | A runtime material builder/compiler. This library is large but contains a full shader compiler/validator/optimizer and supports both OpenGL and Vulkan. |
| [![filamat-android-lite](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite/badge.svg?subject=filamat-android-lite)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite) | A much smaller alternative to `filamat-android` that can only generate OpenGL shaders. It does not provide validation or optimizations. |
| [![filament-android](https://img.shields.io/maven-central/v/com.google.android.filament/filament-android?label=filament-android&color=green)](https://mvnrepository.com/artifact/com.google.android.filament/filament-android) | The Filament rendering engine itself. |
| [![filament-android-debug](https://img.shields.io/maven-central/v/com.google.android.filament/filament-android-debug?label=filament-android-debug&color=green)](https://mvnrepository.com/artifact/com.google.android.filament/filament-android-debug) | Debug version of `filament-android`. |
| [![gltfio-android](https://img.shields.io/maven-central/v/com.google.android.filament/gltfio-android?label=gltfio-android&color=green)](https://mvnrepository.com/artifact/com.google.android.filament/gltfio-android) | A glTF 2.0 loader for Filament, depends on `filament-android`. |
| [![filament-utils-android](https://img.shields.io/maven-central/v/com.google.android.filament/filament-utils-android?label=filament-utils-android&color=green)](https://mvnrepository.com/artifact/com.google.android.filament/filament-utils-android) | KTX loading, Kotlin math, and camera utilities, depends on `gltfio-android`. |
| [![filamat-android](https://img.shields.io/maven-central/v/com.google.android.filament/filamat-android?label=filamat-android&color=green)](https://mvnrepository.com/artifact/com.google.android.filament/filamat-android) | A runtime material builder/compiler. This library is large but contains a full shader compiler/validator/optimizer and supports both OpenGL and Vulkan. |
### iOS
iOS projects can use CocoaPods to install the latest release:
```shell
pod 'Filament', '~> 1.67.1'
pod 'Filament', '~> 1.70.1'
```
## Documentation
@@ -89,7 +88,8 @@ pod 'Filament', '~> 1.67.1'
- OpenGL ES 3.0+ for Android and iOS
- Metal for macOS and iOS
- Vulkan 1.0 for Android, Linux, macOS, and Windows
- WebGL 2.0 for all platforms
- WebGPU for Android, Linux, macOS, and Windows
- WebGL 2.0 for all browsers supporting it
### Rendering
@@ -124,7 +124,7 @@ pod 'Filament', '~> 1.67.1'
- HDR bloom
- Depth of field bokeh
- Multiple tone mappers: generic (customizable), ACES, filmic, etc.
- Multiple tone mappers: PBR Neutral, AgX, generic (customizable), ACES, filmic, etc.
- Color and tone management: luminance scaling, gamut mapping
- Color grading: exposure, night adaptation, white balance, channel mixer,
shadows/mid-tones/highlights, ASC CDL, contrast, saturation, etc.
@@ -158,15 +158,16 @@ pod 'Filament', '~> 1.67.1'
- [x] KHR_draco_mesh_compression
- [x] KHR_lights_punctual
- [x] KHR_materials_clearcoat
- [x] KHR_materials_dispersion
- [x] KHR_materials_emissive_strength
- [x] KHR_materials_ior
- [x] KHR_materials_pbrSpecularGlossiness
- [x] KHR_materials_sheen
- [x] KHR_materials_specular
- [x] KHR_materials_transmission
- [x] KHR_materials_unlit
- [x] KHR_materials_variants
- [x] KHR_materials_volume
- [x] KHR_materials_specular
- [x] KHR_mesh_quantization
- [x] KHR_texture_basisu
- [x] KHR_texture_transform
@@ -331,7 +332,7 @@ and tools.
- `filamesh`: Mesh converter
- `glslminifier`: Minifies GLSL source code
- `matc`: Material compiler
- `filament-matp`: Material parser
- `matedit`: Material editor for compiled materials
- `matinfo` Displays information about materials compiled with `matc`
- `mipgen` Generates a series of miplevels from a source image
- `normal-blending`: Tool to blend normal maps

View File

@@ -7,6 +7,56 @@ A new header is inserted each time a *tag* is created.
Instead, if you are authoring a PR for the main branch, add your release note to
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
## v1.70.1
## v1.70.0
- engine: fix crash when using variance shadow maps
- materials: better shadow normal-bias calculations [⚠️ **New Material Version**]
## v1.69.5
- engine: fix crash when using variance shadow maps
## v1.69.4
## v1.69.3
## v1.69.2
- engine: fix shader compilation failure in TAA material
- engine: fix stereo & parallel shader compilation
## v1.69.1
## v1.69.0
- engine: Support custom attributes morphing, and allow for omitting position and/or normal data. [⚠️ **Recompile Materials**]
## v1.68.5
- engine: "native" Streams are officially deprecated. Use "acquired" streams instead.
- engine: add "engine.skip_frame_when_cpu_ahead_of_display" feature [b/474599530]
## v1.68.4
- gltfio: Add optional support for webp textures (EXT_texture_webp), controlled via FILAMENT_SUPPORTS_WEBP_TEXTURES cmake option
## v1.68.3
- materials: added support for the glTF `KHR_materials_dispersion` extension, which adds dispersion for refractive objects
## v1.68.2
- Support `setPresentationTime` with the Metal backend.
## v1.68.1
## v1.68.0
- engine: add `View::getLastDynamicResolutionScale()` (b/457753622)

View File

@@ -40,15 +40,21 @@
// - Build and upload artifacts with ./gradlew publish
// - Close and release staging repo on Nexus with ./gradlew closeAndReleaseStagingRepository
//
// The following is needed in ~/gradle/gradle.properties:
// The following properties need to be set (either in ~/gradle/gradle.properties, on the command
// line, or as environment variables, e.g.: ORG_GRADLE_PROJECT_property=value):
//
// sonatypeUsername=nexus_user
// sonatypePassword=nexus_password
//
// To sign with a key ring file:
// signing.keyId=pgp_key_id
// signing.password=pgp_key_password
// signing.secretKeyRingFile=/Users/user/.gnupg/maven_signing.key
//
// To sign with in-memory keys (useful for CI):,
// signingKey=ASCII armored key (begins with -----BEGIN PGP PRIVATE KEY BLOCK-----)
// signingPassword=key password
//
buildscript {
def path = providers
@@ -100,7 +106,7 @@ buildscript {
'kotlin': '2.0.21',
'kotlin_coroutines': '1.9.0',
'buildTools': '35.0.0',
'ndk': '27.0.11718014',
'ndk': '29.0.14206865',
'androidx_core': '1.13.1',
'androidx_annotations': '1.9.0'
]
@@ -124,6 +130,7 @@ buildscript {
ext.cmakeArgs = [
"--no-warn-unused-cli",
"-DANDROID_WEAK_API_DEFS=ON",
"-DANDROID_PIE=ON",
"-DANDROID_PLATFORM=21",
"-DANDROID_STL=c++_static",
@@ -193,7 +200,7 @@ subprojects {
google()
}
if (!name.startsWith("sample")) {
if (!name.startsWith("sample") && name != "filament-tools" && name != "gradle-plugin") {
apply plugin: 'com.android.library'
android {

View File

@@ -1,16 +0,0 @@
plugins {
id 'groovy-gradle-plugin'
}
gradlePlugin {
plugins {
create("filament-tools-plugin") {
id = "filament-tools-plugin"
implementationClass = "FilamentToolsPlugin"
}
}
}
repositories {
mavenCentral()
}

View File

@@ -1,359 +0,0 @@
// This plugin accepts the following parameters:
//
// com.google.android.filament.tools-dir
// Path to the Filament distribution/install directory for desktop.
// This directory must contain bin/matc.
//
// com.google.android.filament.exclude-vulkan
// When set, support for Vulkan will be excluded.
//
// Example:
// ./gradlew -Pcom.google.android.filament.tools-dir=../../dist-release assembleDebug
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.file.FileType
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.logging.LogLevel
import org.gradle.api.logging.Logger
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.incremental.InputFileDetails
import org.gradle.api.model.ObjectFactory
import org.gradle.internal.os.OperatingSystem
import org.gradle.process.ExecOperations
import org.gradle.work.ChangeType
import org.gradle.work.Incremental
import org.gradle.work.InputChanges
import java.nio.file.Paths
import javax.inject.Inject
abstract class TaskWithBinary extends DefaultTask {
private final String binaryName
private Property<String> binaryPath = null
TaskWithBinary(String name) {
binaryName = name
}
@Inject abstract ObjectFactory getObjects()
@Inject abstract ProviderFactory getProviders()
@Input
Property<String> getBinary() {
if (binaryPath == null) {
def tool = ["/bin/${binaryName}.exe", "/bin/${binaryName}"]
def fullPath = tool.collect { path ->
def filamentToolsPath = providers
.gradleProperty("com.google.android.filament.tools-dir")
.forUseAtConfigurationTime().get()
def directory = objects.fileProperty()
.fileValue(new File(filamentToolsPath)).getAsFile().get()
Paths.get(directory.absolutePath, path).toFile()
}
binaryPath = objects.property(String.class)
binaryPath.set(
(OperatingSystem.current().isWindows() ? fullPath[0] : fullPath[1]).toString())
}
return binaryPath
}
}
class LogOutputStream extends ByteArrayOutputStream {
private final Logger logger
private final LogLevel level
LogOutputStream(Logger logger, LogLevel level) {
this.logger = logger
this.level = level
}
@Override
void flush() {
logger.log(level, toString())
reset()
}
}
// Custom task to compile material files using matc
// This task handles incremental builds
abstract class MaterialCompiler extends TaskWithBinary {
@Incremental
@InputDirectory
abstract DirectoryProperty getInputDir()
@OutputDirectory
abstract DirectoryProperty getOutputDir()
@Inject abstract FileSystemOperations getFs()
@Inject abstract ExecOperations getExec()
@Inject abstract ObjectFactory getObjects()
@Inject abstract ProviderFactory getProviders()
MaterialCompiler() {
super("matc")
}
@TaskAction
void execute(InputChanges inputs) {
if (!inputs.incremental) {
fs.delete({
delete(objects.fileTree().from(outputDir).matching { include '*.filamat' })
})
}
inputs.getFileChanges(inputDir).each { InputFileDetails change ->
if (change.fileType == FileType.DIRECTORY) return
def file = change.file
if (change.changeType == ChangeType.REMOVED) {
getOutputFile(file).delete()
} else {
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
def err = new LogOutputStream(logger, LogLevel.ERROR)
def header = ("Compiling material " + file + "\n").getBytes()
out.write(header)
out.flush()
if (!new File(binary.get()).exists()) {
throw new GradleException("Could not find ${binary.get()}." +
" Ensure Filament has been built/installed before building this app.")
}
def matcArgs = []
def exclude_vulkan = providers
.gradleProperty("com.google.android.filament.exclude-vulkan")
.forUseAtConfigurationTime().present
if (!exclude_vulkan) {
matcArgs += ['-a', 'vulkan']
}
def include_webgpu = providers
.gradleProperty("com.google.android.filament.include-webgpu")
.forUseAtConfigurationTime().present
if (include_webgpu) {
matcArgs += ['-a', 'webgpu', '--variant-filter=stereo']
}
def mat_no_opt = providers
.gradleProperty("com.google.android.filament.matnopt")
.forUseAtConfigurationTime().present
if (mat_no_opt) {
matcArgs += ['-g']
}
matcArgs += ['-a', 'opengl', '-p', 'mobile', '-o', getOutputFile(file), file]
exec.exec {
standardOutput out
errorOutput err
executable "${binary.get()}"
args matcArgs
}
}
}
}
File getOutputFile(final File file) {
return outputDir.file(file.name[0..file.name.lastIndexOf('.')] + 'filamat').get().asFile
}
}
// Custom task to process IBLs using cmgen
// This task handles incremental builds
abstract class IblGenerator extends TaskWithBinary {
@Input
@Optional
abstract Property<String> getCmgenArgs()
@Incremental
@InputFile
abstract RegularFileProperty getInputFile()
@OutputDirectory
abstract DirectoryProperty getOutputDir()
@Inject abstract FileSystemOperations getFs()
@Inject abstract ExecOperations getExec()
@Inject abstract ObjectFactory getObjects()
IblGenerator() {
super("cmgen")
}
@TaskAction
void execute(InputChanges inputs) {
if (!inputs.incremental) {
fs.delete({
delete(objects.fileTree().from(outputDir).matching { include '*' })
})
}
inputs.getFileChanges(inputFile).each { InputFileDetails change ->
if (change.fileType == FileType.DIRECTORY) return
def file = change.file
if (change.changeType == ChangeType.REMOVED) {
getOutputFile(file).delete()
} else {
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
def err = new LogOutputStream(logger, LogLevel.ERROR)
def header = ("Generating IBL " + file + "\n").getBytes()
out.write(header)
out.flush()
if (!new File(binary.get()).exists()) {
throw new GradleException("Could not find ${binary.get()}." +
" Ensure Filament has been built/installed before building this app.")
}
def outputPath = outputDir.get().asFile
def commandArgs = cmgenArgs.getOrNull()
if (commandArgs == null) {
commandArgs =
'-q -x ' + outputPath + ' --format=rgb32f ' +
'--extract-blur=0.08 --extract=' + outputPath.absolutePath
}
commandArgs = commandArgs + " " + file
exec.exec {
standardOutput out
errorOutput err
executable "${binary.get()}"
args(commandArgs.split())
}
}
}
}
File getOutputFile(final File file) {
return outputDir.file(file.name[0..file.name.lastIndexOf('.') - 1]).get().asFile
}
}
// Custom task to compile mesh files using filamesh
// This task handles incremental builds
abstract class MeshCompiler extends TaskWithBinary {
@Incremental
@InputFile
abstract RegularFileProperty getInputFile()
@OutputDirectory
abstract DirectoryProperty getOutputDir()
@Inject abstract FileSystemOperations getFs()
@Inject abstract ExecOperations getExec()
MeshCompiler() {
super("filamesh")
}
@TaskAction
void execute(InputChanges inputs) {
if (!inputs.incremental) {
fs.delete({
delete(objects.fileTree().from(outputDir).matching { include '*.filamesh' })
})
}
inputs.getFileChanges(inputFile).each { InputFileDetails change ->
if (change.fileType == FileType.DIRECTORY) return
def file = change.file
if (change.changeType == ChangeType.REMOVED) {
getOutputFile(file).delete()
} else {
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
def err = new LogOutputStream(logger, LogLevel.ERROR)
def header = ("Compiling mesh " + file + "\n").getBytes()
out.write(header)
out.flush()
if (!new File(binary.get()).exists()) {
throw new GradleException("Could not find ${binary.get()}." +
" Ensure Filament has been built/installed before building this app.")
}
exec.exec {
standardOutput out
errorOutput err
executable "${binary.get()}"
args(file, getOutputFile(file))
}
}
}
}
File getOutputFile(final File file) {
return outputDir.file(file.name[0..file.name.lastIndexOf('.')] + 'filamesh').get().asFile
}
}
class FilamentToolsPluginExtension {
DirectoryProperty materialInputDir
DirectoryProperty materialOutputDir
String cmgenArgs
RegularFileProperty iblInputFile
DirectoryProperty iblOutputDir
RegularFileProperty meshInputFile
DirectoryProperty meshOutputDir
}
class FilamentToolsPlugin implements Plugin<Project> {
void apply(Project project) {
def extension = project.extensions.create('filamentTools', FilamentToolsPluginExtension)
extension.materialInputDir = project.objects.directoryProperty()
extension.materialOutputDir = project.objects.directoryProperty()
extension.iblInputFile = project.objects.fileProperty()
extension.iblOutputDir = project.objects.directoryProperty()
extension.meshInputFile = project.objects.fileProperty()
extension.meshOutputDir = project.objects.directoryProperty()
project.tasks.register("filamentCompileMaterials", MaterialCompiler) {
enabled =
extension.materialInputDir.isPresent() &&
extension.materialOutputDir.isPresent()
inputDir.set(extension.materialInputDir.getOrNull())
outputDir.set(extension.materialOutputDir.getOrNull())
}
project.preBuild.dependsOn "filamentCompileMaterials"
project.tasks.register("filamentGenerateIbl", IblGenerator) {
enabled = extension.iblInputFile.isPresent() && extension.iblOutputDir.isPresent()
cmgenArgs = extension.cmgenArgs
inputFile = extension.iblInputFile.getOrNull()
outputDir = extension.iblOutputDir.getOrNull()
}
project.preBuild.dependsOn "filamentGenerateIbl"
project.tasks.register("filamentCompileMesh", MeshCompiler) {
enabled = extension.meshInputFile.isPresent() && extension.meshOutputDir.isPresent()
inputFile = extension.meshInputFile.getOrNull()
outputDir = extension.meshOutputDir.getOrNull()
}
project.preBuild.dependsOn "filamentCompileMesh"
}
}

View File

@@ -335,6 +335,13 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRefract
builder->refractionMode((MaterialBuilder::RefractionMode) mode);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderReflectionMode(JNIEnv* env,
jclass, jlong nativeBuilder, jint mode) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->reflectionMode((MaterialBuilder::ReflectionMode) mode);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRefractionType(JNIEnv* env,
jclass, jlong nativeBuilder, jint type) {

View File

@@ -177,6 +177,11 @@ public class MaterialBuilder {
SCREEN_SPACE
}
public enum ReflectionMode {
DEFAULT,
SCREEN_SPACE
}
public enum RefractionType {
SOLID,
THIN
@@ -403,6 +408,12 @@ public class MaterialBuilder {
return this;
}
@NonNull
public MaterialBuilder reflectionMode(ReflectionMode mode) {
nMaterialBuilderReflectionMode(mNativeObject, mode.ordinal());
return this;
}
@NonNull
public MaterialBuilder refractionType(RefractionType type) {
nMaterialBuilderRefractionType(mNativeObject, type.ordinal());
@@ -604,6 +615,7 @@ public class MaterialBuilder {
private static native void nMaterialBuilderSpecularAntiAliasingThreshold(long mNativeObject,
float threshold);
private static native void nMaterialBuilderRefractionMode(long nativeBuilder, int mode);
private static native void nMaterialBuilderReflectionMode(long nativeBuilder, int mode);
private static native void nMaterialBuilderRefractionType(long nativeBuilder, int type);
private static native void nMaterialBuilderClearCoatIorChange(long mNativeObject,
boolean clearCoatIorChange);

View File

@@ -134,6 +134,7 @@ target_include_directories(filament-jni PRIVATE
../../filament/backend/include
../../third_party/robin-map
../../third_party/perfetto
../../libs/bluevk/include
../../libs/utils/include)
# Ordering is significant in the following list. The PRIVATE qualifier prevents transitive deps.
@@ -167,3 +168,9 @@ target_link_libraries(filament-jni
# Force a relink when the version script is changed:
set_target_properties(filament-jni PROPERTIES LINK_DEPENDS ${VERSION_SCRIPT})
if (FILAMENT_SUPPORTS_VULKAN)
add_definitions(-DFILAMENT_SUPPORTS_VULKAN=1)
else()
add_definitions(-DFILAMENT_SUPPORTS_VULKAN=0)
endif()

View File

@@ -18,6 +18,7 @@
#include <filament/Camera.h>
#include <utils/Entity.h>
#include <math/mat4.h>
@@ -40,6 +41,13 @@ Java_com_google_android_filament_Camera_nSetProjectionFov(JNIEnv*, jclass ,
camera->setProjection(fovInDegrees, aspect, near, far, (Camera::Fov) fov);
}
extern "C" JNIEXPORT jdouble JNICALL
Java_com_google_android_filament_Camera_nGetFieldOfViewInDegrees(JNIEnv*, jclass,
jlong nativeCamera, jint direction) {
Camera *camera = (Camera *) nativeCamera;
return camera->getFieldOfViewInDegrees((Camera::Fov) direction);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nSetLensProjection(JNIEnv*, jclass,
jlong nativeCamera, jdouble focalLength, jdouble aspect, jdouble near, jdouble far) {
@@ -62,6 +70,21 @@ Java_com_google_android_filament_Camera_nSetCustomProjection(JNIEnv *env, jclass
env->ReleaseDoubleArrayElements(inProjectionForCulling_, inProjectionForCulling, JNI_ABORT);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nSetCustomEyeProjection(JNIEnv *env, jclass,
jlong nativeCamera, jdoubleArray inProjection_, jint count, jdoubleArray inProjectionForCulling_,
jdouble near, jdouble far) {
Camera *camera = (Camera *) nativeCamera;
jdouble *inProjection = env->GetDoubleArrayElements(inProjection_, NULL);
jdouble *inProjectionForCulling = env->GetDoubleArrayElements(inProjectionForCulling_, NULL);
camera->setCustomEyeProjection(
reinterpret_cast<const filament::math::mat4 *>(inProjection), (size_t) count,
*reinterpret_cast<const filament::math::mat4 *>(inProjectionForCulling),
near, far);
env->ReleaseDoubleArrayElements(inProjection_, inProjection, JNI_ABORT);
env->ReleaseDoubleArrayElements(inProjectionForCulling_, inProjectionForCulling, JNI_ABORT);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nSetScaling(JNIEnv* env, jclass,
jlong nativeCamera, jdouble x, jdouble y) {
@@ -76,6 +99,17 @@ Java_com_google_android_filament_Camera_nSetShift(JNIEnv* env, jclass,
camera->setShift({(double)x, (double)y});
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nGetShift(JNIEnv* env, jclass,
jlong nativeCamera, jdoubleArray out_) {
Camera *camera = (Camera *) nativeCamera;
jdouble *out = env->GetDoubleArrayElements(out_, NULL);
filament::math::double2 s = camera->getShift();
out[0] = s.x;
out[1] = s.y;
env->ReleaseDoubleArrayElements(out_, out, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nLookAt(JNIEnv*, jclass, jlong nativeCamera,
jdouble eye_x, jdouble eye_y, jdouble eye_z, jdouble center_x, jdouble center_y,
@@ -115,6 +149,15 @@ Java_com_google_android_filament_Camera_nSetModelMatrixFp64(JNIEnv *env, jclass,
env->ReleaseDoubleArrayElements(in_, in, JNI_ABORT);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nSetEyeModelMatrix(JNIEnv *env, jclass,
jlong nativeCamera, jint eyeId, jdoubleArray model_) {
Camera* camera = (Camera *) nativeCamera;
jdouble *model = env->GetDoubleArrayElements(model_, NULL);
camera->setEyeModelMatrix((uint8_t)eyeId, *reinterpret_cast<const filament::math::mat4*>(model));
env->ReleaseDoubleArrayElements(model_, model, JNI_ABORT);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nGetProjectionMatrix(JNIEnv *env, jclass,
jlong nativeCamera, jdoubleArray out_) {
@@ -280,3 +323,5 @@ Java_com_google_android_filament_Camera_nComputeEffectiveFov(JNIEnv*, jclass,
jdouble fovInDegrees, jdouble focusDistance) {
return Camera::computeEffectiveFov(fovInDegrees, focusDistance);
}

View File

@@ -18,6 +18,7 @@
#include <filament/Camera.h>
#include <filament/Engine.h>
#include <filament/MorphTargetBuffer.h>
#include <utils/Entity.h>
#include <utils/EntityManager.h>
@@ -207,6 +208,14 @@ Java_com_google_android_filament_Engine_nDestroySkinningBuffer(JNIEnv*, jclass,
return engine->destroy(skinningBuffer);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyMorphTargetBuffer(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeMorphTargetBuffer) {
Engine* engine = (Engine*) nativeEngine;
MorphTargetBuffer* mtb = (MorphTargetBuffer*) nativeMorphTargetBuffer;
return engine->destroy(mtb);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyIndirectLight(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeIndirectLight) {
@@ -328,6 +337,13 @@ Java_com_google_android_filament_Engine_nIsValidSkinningBuffer(JNIEnv*, jclass,
return (jboolean)engine->isValid((SkinningBuffer*)nativeSkinningBuffer);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidMorphTargetBuffer(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeMorphTargetBuffer) {
Engine* engine = (Engine*) nativeEngine;
return (jboolean) engine->isValid((MorphTargetBuffer*) nativeMorphTargetBuffer);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidIndirectLight(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeIndirectLight) {

View File

@@ -25,7 +25,7 @@ using namespace filament;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Material_nBuilderBuild(JNIEnv *env, jclass,
jlong nativeEngine, jobject buffer_, jint size, jint shBandCount, jint shadowQuality) {
jlong nativeEngine, jobject buffer_, jint size, jint shBandCount, jint shadowQuality, jint uboBatchingMode) {
Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, buffer_, size);
auto builder = Material::Builder();
@@ -33,6 +33,7 @@ Java_com_google_android_filament_Material_nBuilderBuild(JNIEnv *env, jclass,
builder.sphericalHarmonicsBandCount(shBandCount);
}
builder.shadowSamplingQuality((Material::Builder::ShadowSamplingQuality)shadowQuality);
builder.uboBatching((Material::UboBatchingMode)uboBatchingMode);
Material* material = builder
.package(buffer.getData(), buffer.getSize())
.build(*engine);
@@ -95,6 +96,14 @@ Java_com_google_android_filament_Material_nGetBlendingMode(JNIEnv*, jclass,
return (jint) material->getBlendingMode();
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_google_android_filament_Material_nGetTransparencyMode(JNIEnv*, jclass,
jlong nativeMaterial) {
Material* material = (Material*) nativeMaterial;
return (jint) material->getTransparencyMode();
}
extern "C"
JNIEXPORT jint JNICALL

View File

@@ -564,3 +564,19 @@ Java_com_google_android_filament_MaterialInstance_nGetDepthFunc(JNIEnv* env, jcl
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
return (jint)instance->getDepthFunc();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetTransparencyMode(JNIEnv*, jclass,
jlong nativeMaterialInstance, jint mode) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setTransparencyMode((MaterialInstance::TransparencyMode) mode);
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_google_android_filament_MaterialInstance_nGetTransparencyMode(JNIEnv*, jclass,
jlong nativeMaterialInstance) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
return (jint) instance->getTransparencyMode();
}

View File

@@ -58,6 +58,27 @@ Java_com_google_android_filament_MorphTargetBuffer_nBuilderCount(JNIEnv*, jclass
builder->count((size_t) count);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_MorphTargetBuffer_nBuilderWithPositions(JNIEnv*, jclass,
jlong nativeBuilder, jboolean enabled) {
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder*) nativeBuilder;
builder->withPositions(enabled);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_MorphTargetBuffer_nBuilderWithTangents(JNIEnv*, jclass,
jlong nativeBuilder, jboolean enabled) {
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder*) nativeBuilder;
builder->withTangents(enabled);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_MorphTargetBuffer_nBuilderEnableCustomMorphing(JNIEnv*,
jclass, jlong nativeBuilder, jboolean enabled) {
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder*) nativeBuilder;
builder->enableCustomMorphing(enabled);
}
extern "C"
JNIEXPORT jlong JNICALL
Java_com_google_android_filament_MorphTargetBuffer_nBuilderBuild(JNIEnv*, jclass,
@@ -112,3 +133,24 @@ Java_com_google_android_filament_MorphTargetBuffer_nGetCount(JNIEnv*, jclass,
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeObject;
return (jint)morphTargetBuffer->getCount();
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_MorphTargetBuffer_nHasPositions(JNIEnv*, jclass,
jlong nativeObject) {
MorphTargetBuffer* morphTargetBuffer = (MorphTargetBuffer*) nativeObject;
return (jboolean) morphTargetBuffer->hasPositions();
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_MorphTargetBuffer_nHasTangents(JNIEnv*, jclass,
jlong nativeObject) {
MorphTargetBuffer* morphTargetBuffer = (MorphTargetBuffer*) nativeObject;
return (jboolean) morphTargetBuffer->hasTangents();
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_MorphTargetBuffer_nIsCustomMorphingEnabled(JNIEnv*, jclass,
jlong nativeObject) {
MorphTargetBuffer* morphTargetBuffer = (MorphTargetBuffer*) nativeObject;
return (jboolean) morphTargetBuffer->isCustomMorphingEnabled();
}

View File

@@ -366,6 +366,13 @@ Java_com_google_android_filament_RenderableManager_nSetPriority(JNIEnv*, jclass,
rm->setPriority((RenderableManager::Instance) i, (uint8_t) priority);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_RenderableManager_nGetPriority(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
return (jint) rm->getPriority((RenderableManager::Instance) i);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetChannel(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jint channel) {
@@ -373,6 +380,13 @@ Java_com_google_android_filament_RenderableManager_nSetChannel(JNIEnv*, jclass,
rm->setChannel((RenderableManager::Instance) i, (uint8_t) channel);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_RenderableManager_nGetChannel(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
return (jint) rm->getChannel((RenderableManager::Instance) i);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetCulling(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jboolean enabled) {
@@ -380,6 +394,13 @@ Java_com_google_android_filament_RenderableManager_nSetCulling(JNIEnv*, jclass,
rm->setCulling((RenderableManager::Instance) i, enabled);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_RenderableManager_nIsCullingEnabled(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
return (jboolean) rm->isCullingEnabled((RenderableManager::Instance) i);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetFogEnabled(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jboolean enabled) {
@@ -429,6 +450,13 @@ Java_com_google_android_filament_RenderableManager_nIsShadowReceiver(JNIEnv*, jc
return (jboolean) rm->isShadowReceiver((RenderableManager::Instance) i);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_RenderableManager_nIsScreenSpaceContactShadowsEnabled(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
return (jboolean) rm->isScreenSpaceContactShadowsEnabled((RenderableManager::Instance) i);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nGetAxisAlignedBoundingBox(JNIEnv* env,
jclass, jlong nativeRenderableManager, jint i, jfloatArray center_,
@@ -500,6 +528,13 @@ Java_com_google_android_filament_RenderableManager_nSetBlendOrderAt(JNIEnv*, jcl
(uint16_t) blendOrder);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_RenderableManager_nGetBlendOrderAt(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jint primitiveIndex) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
return (jint) rm->getBlendOrderAt((RenderableManager::Instance) i, (size_t) primitiveIndex);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetGlobalBlendOrderEnabledAt(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jint primitiveIndex, jboolean enabled) {
@@ -508,6 +543,13 @@ Java_com_google_android_filament_RenderableManager_nSetGlobalBlendOrderEnabledAt
(bool) enabled);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_RenderableManager_nIsGlobalBlendOrderEnabledAt(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jint primitiveIndex) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
return (jboolean) rm->isGlobalBlendOrderEnabledAt((RenderableManager::Instance) i, (size_t) primitiveIndex);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_RenderableManager_nGetEnabledAttributesAt(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jint primitiveIndex) {

View File

@@ -63,6 +63,14 @@ Java_com_google_android_filament_Skybox_nBuilderColor(JNIEnv *, jclass,
builder->color({r, g, b, a});
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_Skybox_nBuilderPriority(JNIEnv *, jclass,
jlong nativeSkyBoxBuilder, jint priority) {
Skybox::Builder *builder = (Skybox::Builder *) nativeSkyBoxBuilder;
builder->priority(uint8_t(priority));
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Skybox_nBuilderBuild(JNIEnv *env, jclass type,
jlong nativeSkyBoxBuilder, jlong nativeEngine) {

View File

@@ -21,6 +21,11 @@
#ifdef __ANDROID__
#include <android/bitmap.h>
#include <android/hardware_buffer_jni.h>
#include <backend/platforms/PlatformEGLAndroid.h>
# if FILAMENT_SUPPORTS_VULKAN
# include <backend/platforms/VulkanPlatformAndroid.h>
# endif
#endif
#include <filament/Engine.h>
@@ -168,6 +173,13 @@ Java_com_google_android_filament_Texture_nBuilderSwizzle(JNIEnv *, jclass ,
(Texture::Swizzle)r, (Texture::Swizzle)g, (Texture::Swizzle)b, (Texture::Swizzle)a);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Texture_nBuilderSamples(JNIEnv*, jclass,
jlong nativeBuilder, jint samples) {
Texture::Builder *builder = (Texture::Builder *) nativeBuilder;
builder->samples((uint8_t) samples);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_Texture_nBuilderImportTexture(JNIEnv*, jclass, jlong nativeBuilder, jlong id) {
@@ -388,6 +400,57 @@ Java_com_google_android_filament_Texture_nSetExternalImage(JNIEnv*, jclass, jlon
texture->setExternalImage(*engine, (void*)eglImage);
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Texture_nSetExternalImageByAHB(JNIEnv *env, jclass clazz,
jlong nativeTexture, jlong nativeEngine, jobject ahb) {
Texture *texture = (Texture *) nativeTexture;
Engine *engine = (Engine *) nativeEngine;
#ifdef __ANDROID__
Platform* platform = engine->getPlatform();
AHardwareBuffer* nativeBuffer = nullptr;
if (__builtin_available(android 26, *)) {
nativeBuffer = AHardwareBuffer_fromHardwareBuffer(env, ahb);
}
if (!nativeBuffer) {
// either we're not on Android 26, or ahb wasn't a AHardwareBuffer
return JNI_FALSE;
}
if (engine->getBackend() == Backend::OPENGL) {
// CAVEAT: we assume that Backend::OPENGL on Android implies PlatformEGLAndroid.
#if UTILS_HAS_RTTI
if (!dynamic_cast<PlatformEGLAndroid*>(platform)) {
return JNI_FALSE;
}
#endif
auto* eglPlatform = (PlatformEGLAndroid*) platform;
auto ref = eglPlatform->createExternalImage(nativeBuffer, false);
texture->setExternalImage(*engine, ref);
}
#if FILAMENT_SUPPORTS_VULKAN
else if (engine->getBackend() == Backend::VULKAN) {
// CAVEAT: we assume that Backend::VULKAN on Android implies VulkanPlatformAndroid.
#if UTILS_HAS_RTTI
if (!dynamic_cast<VulkanPlatformAndroid*>(platform)) {
return JNI_FALSE;
}
#endif
auto* vulkanPlatform = (VulkanPlatformAndroid*) platform;
auto ref = vulkanPlatform->createExternalImage(nativeBuffer, false);
texture->setExternalImage(*engine, ref);
}
#endif // FILAMENT_SUPPORTS_VULKAN
// success!
return JNI_TRUE;
#else
// other platforms could come here
return JNI_FALSE;
#endif // __ANDROID__
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Texture_nSetExternalStream(JNIEnv*, jclass,
jlong nativeTexture, jlong nativeEngine, jlong nativeStream) {
@@ -607,3 +670,4 @@ Java_com_google_android_filament_android_TextureHelper_nSetBitmapWithCallback(JN
}
#endif

View File

@@ -52,6 +52,11 @@ Java_com_google_android_filament_ToneMapper_nCreatePBRNeutralToneMapper(JNIEnv*,
return (jlong) new PBRNeutralToneMapper();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_ToneMapper_nCreateGT7ToneMapper(JNIEnv*, jclass) {
return (jlong) new GT7ToneMapper();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_ToneMapper_nCreateAgxToneMapper(JNIEnv*, jclass, jint look) {
return (jlong) new AgxToneMapper(AgxToneMapper::AgxLook(look));

View File

@@ -76,6 +76,12 @@ Java_com_google_android_filament_View_nSetVisibleLayers(JNIEnv*, jclass, jlong n
view->setVisibleLayers((uint8_t) select, (uint8_t) value);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_View_nGetVisibleLayers(JNIEnv*, jclass, jlong nativeView) {
View* view = (View*) nativeView;
return view->getVisibleLayers();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetShadowingEnabled(JNIEnv*, jclass, jlong nativeView, jboolean enabled) {
View* view = (View*) nativeView;
@@ -440,6 +446,18 @@ Java_com_google_android_filament_View_nIsShadowingEnabled(JNIEnv *, jclass, jlon
return (jboolean)view->isShadowingEnabled();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetFrustumCullingEnabled(JNIEnv*, jclass, jlong nativeView, jboolean enabled) {
View* view = (View*) nativeView;
view->setFrustumCullingEnabled(enabled);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_View_nIsFrustumCullingEnabled(JNIEnv*, jclass, jlong nativeView) {
View* view = (View*) nativeView;
return (jboolean)view->isFrustumCullingEnabled();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetScreenSpaceRefractionEnabled(JNIEnv *, jclass,

View File

@@ -136,4 +136,13 @@ final class Asserts {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 4");
}
}
@NonNull @Size(min = 2)
static double[] assertDouble2(@Nullable double[] out) {
if (out == null) out = new double[2];
else if (out.length < 2) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 2");
}
return out;
}
}

View File

@@ -343,6 +343,27 @@ public class Camera {
nSetScaling(getNativeObject(), xscaling, yscaling);
}
/**
* Sets a custom projection matrix for each eye.
*
* @param inProjection An array of projection matrices, one for each eye.
* Must have at least 16 * count elements.
* @param count Number of eyes to set.
* @param inProjectionForCulling Custom projection matrix for culling, must encompass all eyes.
* @param near Distance to the near plane.
* @param far Distance to the far plane.
*/
public void setCustomEyeProjection(
@NonNull double[] inProjection, int count,
@NonNull @Size(min = 16) double[] inProjectionForCulling,
double near, double far) {
Asserts.assertMat4dIn(inProjectionForCulling);
if (inProjection.length < 16 * count) {
throw new IllegalArgumentException("inProjection array too small for the given count");
}
nSetCustomEyeProjection(getNativeObject(), inProjection, count, inProjectionForCulling, near, far);
}
/**
* Sets an additional matrix that scales the projection matrix.
*
@@ -399,6 +420,31 @@ public class Camera {
nSetShift(getNativeObject(), xshift, yshift);
}
/**
* Returns the shift amount used to translate the projection matrix.
*
* @param out A 2-double array where the shift will be stored, or null.
* @return A 2-double array containing the x and y shift.
*/
@NonNull @Size(min = 2)
public double[] getShift(@Nullable @Size(min = 2) double[] out) {
out = Asserts.assertDouble2(out);
nGetShift(getNativeObject(), out);
return out;
}
/**
* Returns the camera's field of view in degrees.
*
* @param direction The direction of the FOV (VERTICAL or HORIZONTAL).
* @return The field of view in degrees.
*/
public double getFieldOfViewInDegrees(@NonNull Fov direction) {
return nGetFieldOfViewInDegrees(getNativeObject(), direction.ordinal());
}
/**
* Sets the camera's model matrix.
* <p>
@@ -745,6 +791,17 @@ public class Camera {
return mEntity;
}
/**
* Sets the model matrix for a specific eye.
*
* @param eyeId The index of the eye.
* @param model The model matrix for the eye.
*/
public void setEyeModelMatrix(int eyeId, @NonNull @Size(min = 16) double[] model) {
Asserts.assertMat4dIn(model);
nSetEyeModelMatrix(getNativeObject(), eyeId, model);
}
/**
* Helper to compute the effective focal length taking into account the focus distance
*
@@ -784,8 +841,13 @@ public class Camera {
private static native void nSetCustomProjection(long nativeCamera, double[] inProjection, double[] inProjectionForCulling, double near, double far);
private static native void nSetScaling(long nativeCamera, double x, double y);
private static native void nSetShift(long nativeCamera, double x, double y);
private static native void nGetShift(long nativeCamera, double[] out);
private static native void nSetModelMatrix(long nativeCamera, float[] in);
private static native void nSetModelMatrixFp64(long nativeCamera, double[] in);
private static native void nSetEyeModelMatrix(long nativeCamera, int eyeId, double[] model);
private static native void nSetCustomEyeProjection(long nativeCamera, double[] inProjection, int count, double[] inProjectionForCulling, double near, double far);
private static native double nGetFieldOfViewInDegrees(long nativeCamera, int direction);
private static native void nLookAt(long nativeCamera, double eyeX, double eyeY, double eyeZ, double centerX, double centerY, double centerZ, double upX, double upY, double upZ);
private static native double nGetNear(long nativeCamera);
private static native double nGetCullingFar(long nativeCamera);

View File

@@ -939,6 +939,15 @@ public class Engine {
return nIsValidSkinningBuffer(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidMorphTargetBuffer(@NonNull MorphTargetBuffer object) {
return nIsValidMorphTargetBuffer(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
@@ -1192,6 +1201,15 @@ public class Engine {
skinningBuffer.clearNativeObject();
}
/**
* Destroys a {@link MorphTargetBuffer} and frees all its associated resources.
* @param morphTargetBuffer the {@link MorphTargetBuffer} to destroy
*/
public void destroyMorphTargetBuffer(@NonNull MorphTargetBuffer morphTargetBuffer) {
assertDestroy(nDestroyMorphTargetBuffer(getNativeObject(), morphTargetBuffer.getNativeObject()));
morphTargetBuffer.clearNativeObject();
}
/**
* Destroys a {@link IndirectLight} and frees all its associated resources.
* @param ibl the {@link IndirectLight} to destroy
@@ -1483,6 +1501,7 @@ public class Engine {
private static native boolean nDestroyIndexBuffer(long nativeEngine, long nativeIndexBuffer);
private static native boolean nDestroyVertexBuffer(long nativeEngine, long nativeVertexBuffer);
private static native boolean nDestroySkinningBuffer(long nativeEngine, long nativeSkinningBuffer);
private static native boolean nDestroyMorphTargetBuffer(long nativeEngine, long nativeMorphTargetBuffer);
private static native boolean nDestroyIndirectLight(long nativeEngine, long nativeIndirectLight);
private static native boolean nDestroyMaterial(long nativeEngine, long nativeMaterial);
private static native boolean nDestroyMaterialInstance(long nativeEngine, long nativeMaterialInstance);
@@ -1499,6 +1518,7 @@ public class Engine {
private static native boolean nIsValidIndexBuffer(long nativeEngine, long nativeIndexBuffer);
private static native boolean nIsValidVertexBuffer(long nativeEngine, long nativeVertexBuffer);
private static native boolean nIsValidSkinningBuffer(long nativeEngine, long nativeSkinningBuffer);
private static native boolean nIsValidMorphTargetBuffer(long nativeEngine, long nativeMorphTargetBuffer);
private static native boolean nIsValidIndirectLight(long nativeEngine, long nativeIndirectLight);
private static native boolean nIsValidMaterial(long nativeEngine, long nativeMaterial);
private static native boolean nIsValidMaterialInstance(long nativeEngine, long nativeMaterial, long nativeMaterialInstance);

View File

@@ -54,6 +54,7 @@ public class Material {
static final CullingMode[] sCullingModeValues = CullingMode.values();
static final VertexBuffer.VertexAttribute[] sVertexAttributeValues =
VertexBuffer.VertexAttribute.values();
static final TransparencyMode[] sTransparencyModeValues = TransparencyMode.values();
}
private long mNativeObject;
@@ -160,6 +161,31 @@ public class Material {
SCREEN,
}
/**
* How transparent objects are handled
*
* @see
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/blendingandtransparency:transparencymode">
* Blending and transparency: transparencyMode</a>
*/
public enum TransparencyMode {
/** The transparent object is drawn honoring the raster state. */
DEFAULT,
/**
* The transparent object is first drawn in the depth buffer,
* then in the color buffer, honoring the culling mode, but ignoring the depth test function.
*/
TWO_PASSES_ONE_SIDE,
/**
* The transparent object is drawn twice in the color buffer,
* first with back faces only, then with front faces; the culling
* mode is ignored. Can be combined with two-sided lighting.
*/
TWO_PASSES_TWO_SIDES
}
/**
* Supported refraction modes
*
@@ -261,6 +287,20 @@ public class Material {
LOW
}
/**
* Defines whether a material instance should use UBO batching or not.
*/
public enum UboBatchingMode {
/**
* For default, it follows the engine settings.
* If UBO batching is enabled on the engine and the material domain is SURFACE, it
* turns on the UBO batching. Otherwise, it turns off the UBO batching.
*/
DEFAULT,
/** Disable the Ubo Batching for this material */
DISABLED
}
public static class UserVariantFilterBit {
/** Directional lighting */
public static int DIRECTIONAL_LIGHTING = 0x01;
@@ -372,6 +412,7 @@ public class Material {
private int mSize;
private int mShBandCount = 0;
private ShadowSamplingQuality mShadowSamplingQuality = ShadowSamplingQuality.LOW;
private UboBatchingMode mUboBatchingMode = UboBatchingMode.DEFAULT;
/**
@@ -416,6 +457,17 @@ public class Material {
return this;
}
/**
* Set the batching mode of the instances created from this material.
* @param uboBatchingMode
* @return Reference to this Builder for chaining calls.
*/
@NonNull
public Builder uboBatching(UboBatchingMode mode) {
mUboBatchingMode = mode;
return this;
}
/**
* Creates and returns the Material object.
*
@@ -428,7 +480,7 @@ public class Material {
@NonNull
public Material build(@NonNull Engine engine) {
long nativeMaterial = nBuilderBuild(engine.getNativeObject(),
mBuffer, mSize, mShBandCount, mShadowSamplingQuality.ordinal());
mBuffer, mSize, mShBandCount, mShadowSamplingQuality.ordinal(), mUboBatchingMode.ordinal());
if (nativeMaterial == 0) throw new IllegalStateException("Couldn't create Material");
return new Material(nativeMaterial);
}
@@ -561,6 +613,18 @@ public class Material {
return EnumCache.sBlendingModeValues[nGetBlendingMode(getNativeObject())];
}
/**
* Returns the transparency mode of this material.
* This value only makes sense when the blending mode is transparent or fade.
*
* @see
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/blendingandtransparency:transparencymode">
* Blending and transparency: transparencyMode</a>
*/
public TransparencyMode getTransparencyMode() {
return EnumCache.sTransparencyModeValues[nGetTransparencyMode(getNativeObject())];
}
/**
* Returns the refraction mode of this material.
*
@@ -1094,7 +1158,7 @@ public class Material {
mNativeObject = 0;
}
private static native long nBuilderBuild(long nativeEngine, @NonNull Buffer buffer, int size, int shBandCount, int shadowQuality);
private static native long nBuilderBuild(long nativeEngine, @NonNull Buffer buffer, int size, int shBandCount, int shadowQuality, int uboBatchingMode);
private static native long nCreateInstance(long nativeMaterial);
private static native long nCreateInstanceWithName(long nativeMaterial, @NonNull String name);
private static native long nGetDefaultInstance(long nativeMaterial);
@@ -1104,6 +1168,7 @@ public class Material {
private static native int nGetShading(long nativeMaterial);
private static native int nGetInterpolation(long nativeMaterial);
private static native int nGetBlendingMode(long nativeMaterial);
private static native int nGetTransparencyMode(long nativeMaterial);
private static native int nGetVertexDomain(long nativeMaterial);
private static native int nGetCullingMode(long nativeMaterial);
private static native boolean nIsColorWriteEnabled(long nativeMaterial);

View File

@@ -537,6 +537,14 @@ public class MaterialInstance {
nSetDoubleSided(getNativeObject(), doubleSided);
}
/**
* Sets the transparency mode for this material instance.
* @see Material.TransparencyMode
*/
public void setTransparencyMode(@NonNull Material.TransparencyMode mode) {
nSetTransparencyMode(getNativeObject(), mode.ordinal());
}
/**
* Returns whether double-sided lighting is enabled when the parent Material has double-sided
* capability.
@@ -545,6 +553,14 @@ public class MaterialInstance {
return nIsDoubleSided(getNativeObject());
}
/**
* Returns the transparency mode.
*/
@NonNull
public Material.TransparencyMode getTransparencyMode() {
return Material.EnumCache.sTransparencyModeValues[nGetTransparencyMode(getNativeObject())];
}
/**
* Overrides the default triangle culling state that was set on the material.
*
@@ -982,4 +998,6 @@ public class MaterialInstance {
private static native boolean nIsStencilWriteEnabled(long nativeMaterialInstance);
private static native boolean nIsDepthCullingEnabled(long nativeMaterialInstance);
private static native int nGetDepthFunc(long nativeMaterialInstance);
private static native void nSetTransparencyMode(long nativeMaterialInstance, int mode);
private static native int nGetTransparencyMode(long nativeMaterialInstance);
}

View File

@@ -64,6 +64,45 @@ public class MorphTargetBuffer {
return this;
}
/**
* Use this method to enable or disable the built-in position morphing buffer.
* Default is true.
*
* @param enabled true to enable, false to disable
* @return this <code>Builder</code> object for chaining calls
*/
@NonNull
public Builder withPositions(boolean enabled) {
nBuilderWithPositions(mNativeBuilder, enabled);
return this;
}
/**
* Use this method to enable or disable the built-in tangent morphing buffer.
* Default is true.
*
* @param enabled true to enable, false to disable
* @return this <code>Builder</code> object for chaining calls
*/
@NonNull
public Builder withTangents(boolean enabled) {
nBuilderWithTangents(mNativeBuilder, enabled);
return this;
}
/**
* Use this method to enable or disable custom morphing.
* Default is false.
*
* @param enabled true to enable, false to disable
* @return this <code>Builder</code> object for chaining calls
*/
@NonNull
public Builder enableCustomMorphing(boolean enabled) {
nBuilderEnableCustomMorphing(mNativeBuilder, enabled);
return this;
}
/**
* Creates and returns the <code>MorphTargetBuffer</code> object.
*
@@ -156,6 +195,27 @@ public class MorphTargetBuffer {
return nGetCount(mNativeObject);
}
/**
* @return true if this MorphTargetBuffer has a position buffer.
*/
public boolean hasPositions() {
return nHasPositions(mNativeObject);
}
/**
* @return true if this MorphTargetBuffer has a tangent buffer.
*/
public boolean hasTangents() {
return nHasTangents(mNativeObject);
}
/**
* @return true if custom morphing is enabled.
*/
public boolean isCustomMorphingEnabled() {
return nIsCustomMorphingEnabled(mNativeObject);
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed MorphTargetBuffer");
@@ -171,10 +231,16 @@ public class MorphTargetBuffer {
private static native void nDestroyBuilder(long nativeBuilder);
private static native void nBuilderVertexCount(long nativeBuilder, int vertexCount);
private static native void nBuilderCount(long nativeBuilder, int count);
private static native void nBuilderWithPositions(long nativeBuilder, boolean enabled);
private static native void nBuilderWithTangents(long nativeBuilder, boolean enabled);
private static native void nBuilderEnableCustomMorphing(long nativeBuilder, boolean enabled);
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
private static native int nSetPositionsAt(long nativeObject, long nativeEngine, int targetIndex, float[] positions, int count);
private static native int nSetTangentsAt(long nativeObject, long nativeEngine, int targetIndex, short[] tangents, int count);
private static native int nGetVertexCount(long nativeObject);
private static native int nGetCount(long nativeObject);
private static native boolean nHasPositions(long nativeObject);
private static native boolean nHasTangents(long nativeObject);
private static native boolean nIsCustomMorphingEnabled(long nativeObject);
}

View File

@@ -346,8 +346,8 @@ public class RenderableManager {
*
* @return Builder reference for chaining calls.
*
* @see Builder::blendOrder()
* @see Builder::priority()
* @see Builder#blendOrder()
* @see Builder#priority()
* @see RenderableManager::setBlendOrderAt()
*/
@NonNull
@@ -725,6 +725,10 @@ public class RenderableManager {
nSetPriority(mNativeObject, i, priority);
}
public int getPriority(@EntityInstance int i) {
return nGetPriority(mNativeObject, i);
}
/**
* Changes the channel of a renderable
*
@@ -734,6 +738,10 @@ public class RenderableManager {
nSetChannel(mNativeObject, i, channel);
}
public int getChannel(@EntityInstance int i) {
return nGetChannel(mNativeObject, i);
}
/**
* Changes whether or not frustum culling is on.
*
@@ -743,6 +751,10 @@ public class RenderableManager {
nSetCulling(mNativeObject, i, enabled);
}
public boolean isCullingEnabled(@EntityInstance int i) {
return nIsCullingEnabled(mNativeObject, i);
}
/**
* Changes whether or not the large-scale fog is applied to this renderable
* @see Builder#fog
@@ -812,6 +824,10 @@ public class RenderableManager {
nSetScreenSpaceContactShadows(mNativeObject, i, enabled);
}
public boolean isScreenSpaceContactShadowsEnabled(@EntityInstance int i) {
return nIsScreenSpaceContactShadowsEnabled(mNativeObject, i);
}
/**
* Checks if the renderable can cast shadows.
*
@@ -932,6 +948,10 @@ public class RenderableManager {
nSetBlendOrderAt(mNativeObject, instance, primitiveIndex, blendOrder);
}
public int getBlendOrderAt(@EntityInstance int instance, @IntRange(from = 0) int primitiveIndex) {
return nGetBlendOrderAt(mNativeObject, instance, primitiveIndex);
}
/**
* Changes whether the blend order is global or local to this Renderable (by default).
*
@@ -946,6 +966,10 @@ public class RenderableManager {
nSetGlobalBlendOrderEnabledAt(mNativeObject, instance, primitiveIndex, enabled);
}
public boolean isGlobalBlendOrderEnabledAt(@EntityInstance int instance, @IntRange(from = 0) int primitiveIndex) {
return nIsGlobalBlendOrderEnabledAt(mNativeObject, instance, primitiveIndex);
}
/**
* Retrieves the set of enabled attribute slots in the given primitive's VertexBuffer.
*/
@@ -1013,8 +1037,11 @@ public class RenderableManager {
private static native void nSetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float cx, float cy, float cz, float ex, float ey, float ez);
private static native void nSetLayerMask(long nativeRenderableManager, int i, int select, int value);
private static native void nSetPriority(long nativeRenderableManager, int i, int priority);
private static native int nGetPriority(long nativeRenderableManager, int i);
private static native void nSetChannel(long nativeRenderableManager, int i, int channel);
private static native int nGetChannel(long nativeRenderableManager, int i);
private static native void nSetCulling(long nativeRenderableManager, int i, boolean enabled);
private static native boolean nIsCullingEnabled(long nativeRenderableManager, int i);
private static native void nSetFogEnabled(long nativeRenderableManager, int i, boolean enabled);
private static native boolean nGetFogEnabled(long nativeRenderableManager, int i);
private static native void nSetLightChannel(long nativeRenderableManager, int i, int channel, boolean enable);
@@ -1022,6 +1049,7 @@ public class RenderableManager {
private static native void nSetCastShadows(long nativeRenderableManager, int i, boolean enabled);
private static native void nSetReceiveShadows(long nativeRenderableManager, int i, boolean enabled);
private static native void nSetScreenSpaceContactShadows(long nativeRenderableManager, int i, boolean enabled);
private static native boolean nIsScreenSpaceContactShadowsEnabled(long nativeRenderableManager, int i);
private static native boolean nIsShadowCaster(long nativeRenderableManager, int i);
private static native boolean nIsShadowReceiver(long nativeRenderableManager, int i);
private static native void nGetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float[] center, float[] halfExtent);
@@ -1032,6 +1060,8 @@ public class RenderableManager {
private static native long nGetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex);
private static native void nSetGeometryAt(long nativeRenderableManager, int i, int primitiveIndex, int primitiveType, long nativeVertexBuffer, long nativeIndexBuffer, int offset, int count);
private static native void nSetBlendOrderAt(long nativeRenderableManager, int i, int primitiveIndex, int blendOrder);
private static native int nGetBlendOrderAt(long nativeRenderableManager, int i, int primitiveIndex);
private static native void nSetGlobalBlendOrderEnabledAt(long nativeRenderableManager, int i, int primitiveIndex, boolean enabled);
private static native boolean nIsGlobalBlendOrderEnabledAt(long nativeRenderableManager, int i, int primitiveIndex);
private static native int nGetEnabledAttributesAt(long nativeRenderableManager, int i, int primitiveIndex);
}

View File

@@ -155,6 +155,24 @@ public class Skybox {
return this;
}
/**
* Set the rendering priority of the Skybox. By default, it is set to the lowest
* priority (7) such that the Skybox is always rendered after the opaque objects,
* to reduce overdraw when depth culling is enabled.
*
* @param priority clamped to the range [0..7], defaults to 4; 7 is lowest priority
* (rendered last).
*
* @return Builder reference for chaining calls.
*
* @see RenderableManager.Builder#priority
*/
@NonNull
public Builder priority(@IntRange(from = 0, to = 7) int priority) {
nBuilderPriority(mNativeBuilder, priority);
return this;
}
/**
* Creates a <code>Skybox</code> object
*
@@ -262,6 +280,7 @@ public class Skybox {
private static native void nBuilderShowSun(long nativeSkyboxBuilder, boolean show);
private static native void nBuilderIntensity(long nativeSkyboxBuilder, float intensity);
private static native void nBuilderColor(long nativeSkyboxBuilder, float r, float g, float b, float a);
private static native void nBuilderPriority(long nativeSkyboxBuilder, int priority);
private static native long nBuilderBuild(long nativeSkyboxBuilder, long nativeEngine);
private static native void nSetLayerMask(long nativeSkybox, int select, int value);
private static native int nGetLayerMask(long nativeSkybox);

View File

@@ -71,6 +71,16 @@ import static com.google.android.filament.Texture.Type.COMPRESSED;
* @see MaterialInstance#setParameter(String, Texture, TextureSampler)
*/
public class Texture {
private static Class<?> HardwareBufferClass = null;
static {
try {
HardwareBufferClass = Class.forName("android.hardware.HardwareBuffer");
} catch (ClassNotFoundException ignored) {
}
}
private static final Sampler[] sSamplerValues = Sampler.values();
private static final InternalFormat[] sInternalFormatValues = InternalFormat.values();
@@ -785,6 +795,17 @@ public class Texture {
return this;
}
/**
* Specifies the number of samples for multisample anti-aliasing.
* @param samples number of samples, must be at least 1. Default is 1.
* @return This Builder, for chaining calls.
*/
@NonNull
public Builder samples(@IntRange(from = 1) int samples) {
nBuilderSamples(mNativeBuilder, samples);
return this;
}
/**
* Specifies the texture's internal format.
* <p>The internal format specifies how texels are stored (which may be different from how
@@ -1172,6 +1193,38 @@ public class Texture {
nSetExternalImage(getNativeObject(), engine.getNativeObject(), eglImage);
}
/**
* Specifies the external image to associate with this <code>Texture</code>.
*
* <p>Typically, the external image is OS specific, and can be a video or camera frame.
* There are many restrictions when using an external image as a texture, such as:</p>
* <ul>
* <li> only the level of detail (lod) 0 can be specified</li>
* <li> only nearest or linear filtering is supported</li>
* <li> the size and format of the texture is defined by the external image</li>
* <li> only the CLAMP_TO_EDGE wrap mode is supported</li>
* </ul>
*
* @param engine {@link Engine} this texture is associated to. Must be the
* instance passed to {@link Builder#build Builder.build()}.
* @param externalImageRef An OS specific Object. On Android it must be a
* <code>android.hardware.HardwareBuffer</code>
*/
public void setExternalImage(@NonNull Engine engine, Object externalImageRef) {
if (HardwareBufferClass != null) {
if (!HardwareBufferClass.isInstance(externalImageRef)) {
throw new IllegalArgumentException("externalImageRef must be a AHardwareBuffer");
}
if (!nSetExternalImageByAHB(getNativeObject(), engine.getNativeObject(), externalImageRef)) {
throw new IllegalStateException("Error setting AHardwareBuffer as external image");
}
} else {
throw new UnsupportedOperationException(
"setExternalImage(Engine, Object) not supported on this platform");
}
}
/**
* Specifies the external stream to associate with this <code>Texture</code>.
*
@@ -1328,6 +1381,7 @@ public class Texture {
private static native void nBuilderFormat(long nativeBuilder, int format);
private static native void nBuilderUsage(long nativeBuilder, int flags);
private static native void nBuilderSwizzle(long nativeBuilder, int r, int g, int b, int a);
private static native void nBuilderSamples(long nativeBuilder, int samples);
private static native void nBuilderImportTexture(long nativeBuilder, long id);
private static native void nBuilderExternal(long nativeBuilder);
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
@@ -1364,6 +1418,8 @@ public class Texture {
private static native void nSetExternalImage(
long nativeObject, long nativeEngine, long eglImage);
private static native boolean nSetExternalImageByAHB(long nativeTexture, long nativeObject, Object ahb);
private static native void nSetExternalStream(long nativeTexture,
long nativeEngine, long nativeStream);

View File

@@ -24,6 +24,7 @@ package com.google.android.filament;
* <li>ACESLegacyToneMapper</li>
* <li>FilmicToneMapper</li>
* <li>PBRNeutralToneMapper</li>
* <li>GT7ToneMapper</li>
* </ul>
* <li>Debug/validation tone mapping operators</li>
* <ul>
@@ -111,6 +112,19 @@ public class ToneMapper {
}
}
/**
* Gran Turismo 7 tone mapping operator. This tone mapper was designed
* to preserve the appearance of materials across lighting conditions while
* avoiding artifacts in the highlights in high dynamic range conditions.
* This tone mapper targets an SDR paper white value of 250 nits, with a
* reference luminance of 100 cd/m^2 (a value of 1.0 in the HDR framebuffer).
*/
public static class GT7ToneMapper extends ToneMapper {
public GT7ToneMapper() {
super(nCreateGT7ToneMapper());
}
}
/**
* AgX tone mapping operator.
*/
@@ -244,6 +258,7 @@ public class ToneMapper {
private static native long nCreateACESLegacyToneMapper();
private static native long nCreateFilmicToneMapper();
private static native long nCreatePBRNeutralToneMapper();
private static native long nCreateGT7ToneMapper();
private static native long nCreateAgxToneMapper(int look);
private static native long nCreateGenericToneMapper(
float contrast, float midGrayIn, float midGrayOut, float hdrMax);

View File

@@ -350,6 +350,26 @@ public class View {
nSetVisibleLayers(getNativeObject(), select & 0xFF, values & 0xFF);
}
/**
* Returns the visible layers.
*
* @return a bitmask specifying which layer is visible.
*/
public int getVisibleLayers() {
return nGetVisibleLayers(getNativeObject());
}
/**
* Enables or disables a specific layer.
*
* @param layer Index of the layer to enable or disable, must be between 0 and 7.
* @param enabled True to enable the layer, false to disable it.
*/
public void setLayerEnabled(@IntRange(from = 0, to = 7) int layer, boolean enabled) {
int mask = 1 << layer;
setVisibleLayers(mask, enabled ? mask : 0);
}
/**
* Enables or disables shadow mapping. Enabled by default.
*
@@ -368,6 +388,22 @@ public class View {
return nIsShadowingEnabled(getNativeObject());
}
/**
* Enables or disables frustum culling. Enabled by default.
*
* @param enabled true enables frustum culling, false disables it.
*/
public void setFrustumCullingEnabled(boolean enabled) {
nSetFrustumCullingEnabled(getNativeObject(), enabled);
}
/**
* @return whether frustum culling is enabled
*/
public boolean isFrustumCullingEnabled() {
return nIsFrustumCullingEnabled(getNativeObject());
}
/**
* Enables or disables screen space refraction. Enabled by default.
*
@@ -1322,6 +1358,9 @@ public class View {
private static native boolean nHasCamera(long nativeView);
private static native void nSetViewport(long nativeView, int left, int bottom, int width, int height);
private static native void nSetVisibleLayers(long nativeView, int select, int value);
private static native int nGetVisibleLayers(long nativeView);
private static native void nSetFrustumCullingEnabled(long nativeView, boolean enabled);
private static native boolean nIsFrustumCullingEnabled(long nativeView);
private static native void nSetShadowingEnabled(long nativeView, boolean enabled);
private static native void nSetRenderTarget(long nativeView, long nativeRenderTarget);
private static native void nSetSampleCount(long nativeView, int count);
@@ -1406,65 +1445,59 @@ public class View {
* by lowering the resolution of a View, or to increase the quality when the
* rendering is faster than the target frame rate.
*
* This structure can be used to specify the minimum scale factor used when
* <p>This structure can be used to specify the minimum scale factor used when
* lowering the resolution of a View, and the maximum scale factor used when
* increasing the resolution for higher quality rendering. The scale factors
* can be controlled on each X and Y axis independently. By default, all scale
* factors are set to 1.0.
* factors are set to 1.0.</p>
*
* enabled: enable or disables dynamic resolution on a View
* <ul>
* <li>enabled: enable or disables dynamic resolution on a View</li>
*
* homogeneousScaling: by default the system scales the major axis first. Set this to true
* to force homogeneous scaling.
* <li>homogeneousScaling: by default the system scales the major axis first. Set this to true
* to force homogeneous scaling.</li>
*
* minScale: the minimum scale in X and Y this View should use
* <li>minScale: the minimum scale in X and Y this View should use</li>
*
* maxScale: the maximum scale in X and Y this View should use
* <li>maxScale: the maximum scale in X and Y this View should use</li>
*
* quality: upscaling quality.
* LOW: 1 bilinear tap, Medium: 4 bilinear taps, High: 9 bilinear taps (tent)
* <li>quality: upscaling quality.
* LOW: 1 bilinear tap, Medium: 4 bilinear taps, High: 9 bilinear taps (tent)</li>
* </ul>
*
* \note
* <p>Note:
* Dynamic resolution is only supported on platforms where the time to render
* a frame can be measured accurately. On platforms where this is not supported,
* Dynamic Resolution can't be enabled unless minScale == maxScale.
* Dynamic Resolution can't be enabled unless <code>minScale == maxScale</code>.</p>
*
* @see Renderer::FrameRateOptions
* @see Renderer.FrameRateOptions
*
*/
public static class DynamicResolutionOptions {
/**
* minimum scale factors in x and y
*/
/** minimum scale factors in x and y */
public float minScale = 0.5f;
/**
* maximum scale factors in x and y
*/
/** maximum scale factors in x and y */
public float maxScale = 1.0f;
/**
* sharpness when QualityLevel::MEDIUM or higher is used [0 (disabled), 1 (sharpest)]
*/
/** sharpness when QualityLevel::MEDIUM or higher is used [0 (disabled), 1 (sharpest)] */
public float sharpness = 0.9f;
/**
* enable or disable dynamic resolution
*/
/** enable or disable dynamic resolution */
public boolean enabled = false;
/**
* set to true to force homogeneous scaling
*/
/** set to true to force homogeneous scaling */
public boolean homogeneousScaling = false;
/**
* Upscaling quality
* LOW: bilinear filtered blit. Fastest, poor quality
* MEDIUM: Qualcomm Snapdragon Game Super Resolution (SGSR) 1.0
* HIGH: AMD FidelityFX FSR1 w/ mobile optimizations
* ULTRA: AMD FidelityFX FSR1
* <ul>
* <li>LOW: bilinear filtered blit. Fastest, poor quality</li>
* <li>MEDIUM: Qualcomm Snapdragon Game Super Resolution (SGSR) 1.0</li>
* <li>HIGH: AMD FidelityFX FSR1 w/ mobile optimizations</li>
* <li>ULTRA: AMD FidelityFX FSR1</li>
* </ul>
* FSR1 and SGSR require a well anti-aliased (MSAA or TAA), noise free scene.
* Avoid FXAA and dithering.
*
* The default upscaling quality is set to LOW.
* <p>The default upscaling quality is set to LOW.</p>
*
* caveat: currently, 'quality' is always set to LOW if the View is TRANSLUCENT.
* <p>caveat: currently, <code>quality</code> is always set to LOW if the View is TRANSLUCENT.</p>
*/
@NonNull
public QualityLevel quality = QualityLevel.LOW;
@@ -1473,134 +1506,98 @@ public class View {
/**
* Options to control the bloom effect
*
* enabled: Enable or disable the bloom post-processing effect. Disabled by default.
* <ul>
* <li>enabled: Enable or disable the bloom post-processing effect. Disabled by default.</li>
*
* levels: Number of successive blurs to achieve the blur effect, the minimum is 3 and the
* <li>levels: Number of successive blurs to achieve the blur effect, the minimum is 3 and the
* maximum is 12. This value together with resolution influences the spread of the
* blur effect. This value can be silently reduced to accommodate the original
* image size.
* image size.</li>
*
* resolution: Resolution of bloom's minor axis. The minimum value is 2^levels and the
* <li>resolution: Resolution of bloom's minor axis. The minimum value is 2^levels and the
* the maximum is lower of the original resolution and 4096. This parameter is
* silently clamped to the minimum and maximum.
* It is highly recommended that this value be smaller than the target resolution
* after dynamic resolution is applied (horizontally and vertically).
* after dynamic resolution is applied (horizontally and vertically).</li>
*
* strength: how much of the bloom is added to the original image. Between 0 and 1.
* <li>strength: how much of the bloom is added to the original image. Between 0 and 1.</li>
*
* blendMode: Whether the bloom effect is purely additive (false) or mixed with the original
* image (true).
* <li>blendMode: Whether the bloom effect is purely additive (false) or mixed with the original
* image (true).</li>
*
* threshold: When enabled, a threshold at 1.0 is applied on the source image, this is
* useful for artistic reasons and is usually needed when a dirt texture is used.
* <li>threshold: When enabled, a threshold at 1.0 is applied on the source image, this is
* useful for artistic reasons and is usually needed when a dirt texture is used.</li>
*
* dirt: A dirt/scratch/smudges texture (that can be RGB), which gets added to the
* <li>dirt: A dirt/scratch/smudges texture (that can be RGB), which gets added to the
* bloom effect. Smudges are visible where bloom occurs. Threshold must be
* enabled for the dirt effect to work properly.
* enabled for the dirt effect to work properly.</li>
*
* dirtStrength: Strength of the dirt texture.
* <li>dirtStrength: Strength of the dirt texture.</li>
* </ul>
*/
public static class BloomOptions {
public enum BlendMode {
/**
* Bloom is modulated by the strength parameter and added to the scene
*/
/** Bloom is modulated by the strength parameter and added to the scene */
ADD,
/**
* Bloom is interpolated with the scene using the strength parameter
*/
/** Bloom is interpolated with the scene using the strength parameter */
INTERPOLATE,
}
/**
* user provided dirt texture
*/
/** user provided dirt texture */
@Nullable
public Texture dirt = null;
/**
* strength of the dirt texture
*/
/** strength of the dirt texture */
public float dirtStrength = 0.2f;
/**
* bloom's strength between 0.0 and 1.0
*/
/** bloom's strength between 0.0 and 1.0 */
public float strength = 0.10f;
/**
* resolution of vertical axis (2^levels to 2048)
*/
/** resolution of vertical axis (2^levels to 2048) */
public int resolution = 384;
/**
* number of blur levels (1 to 11)
*/
/** number of blur levels (1 to 11) */
public int levels = 6;
/**
* how the bloom effect is applied
*/
/** how the bloom effect is applied */
@NonNull
public BloomOptions.BlendMode blendMode = BloomOptions.BlendMode.ADD;
/**
* whether to threshold the source
*/
/** whether to threshold the source */
public boolean threshold = true;
/**
* enable or disable bloom
*/
/** enable or disable bloom */
public boolean enabled = false;
/**
* limit highlights to this value before bloom [10, +inf]
*/
/** limit highlights to this value before bloom [10, +inf] */
public float highlight = 1000.0f;
/**
* Bloom quality level.
* LOW (default): use a more optimized down-sampling filter, however there can be artifacts
* with dynamic resolution, this can be alleviated by using the homogenous mode.
* MEDIUM: Good balance between quality and performance.
* HIGH: In this mode the bloom resolution is automatically increased to avoid artifacts.
* <ul>
* <li>LOW (default): use a more optimized down-sampling filter, however there can be artifacts
* with dynamic resolution, this can be alleviated by using the homogenous mode.</li>
* <li>MEDIUM: Good balance between quality and performance.</li>
* <li>HIGH: In this mode the bloom resolution is automatically increased to avoid artifacts.
* This mode can be significantly slower on mobile, especially at high resolution.
* This mode greatly improves the anamorphic bloom.
* This mode greatly improves the anamorphic bloom.</li>
* </ul>
*/
@NonNull
public QualityLevel quality = QualityLevel.LOW;
/**
* enable screen-space lens flare
*/
/** enable screen-space lens flare */
public boolean lensFlare = false;
/**
* enable starburst effect on lens flare
*/
/** enable starburst effect on lens flare */
public boolean starburst = true;
/**
* amount of chromatic aberration
*/
/** amount of chromatic aberration */
public float chromaticAberration = 0.005f;
/**
* number of flare "ghosts"
*/
/** number of flare "ghosts" */
public int ghostCount = 4;
/**
* spacing of the ghost in screen units [0, 1[
*/
/** spacing of the ghost in screen units [0, 1[ */
public float ghostSpacing = 0.6f;
/**
* hdr threshold for the ghosts
*/
/** hdr threshold for the ghosts */
public float ghostThreshold = 10.0f;
/**
* thickness of halo in vertical screen units, 0 to disable
*/
/** thickness of halo in vertical screen units, 0 to disable */
public float haloThickness = 0.1f;
/**
* radius of halo in vertical screen units [0, 0.5]
*/
/** radius of halo in vertical screen units [0, 0.5] */
public float haloRadius = 0.4f;
/**
* hdr threshold for the halo
*/
/** hdr threshold for the halo */
public float haloThreshold = 10.0f;
}
/**
* Options to control large-scale fog in the scene. Materials can enable the `linearFog` property,
* Options to control large-scale fog in the scene. Materials can enable the <code>linearFog</code> property,
* which uses a simplified, linear equation for fog calculation; in this mode, the heightFalloff
* is ignored as well as the mipmap selection in IBL or skyColor mode.
*/
@@ -1614,12 +1611,12 @@ public class View {
* This can be used to exclude the skybox, which is desirable if it already contains clouds or
* fog. The default value is +infinity which applies the fog to everything.
*
* Note: The SkyBox is typically at a distance of 1e19 in world space (depending on the near
* plane distance and projection used though).
* <p>Note: The SkyBox is typically at a distance of 1e19 in world space (depending on the near
* plane distance and projection used though).</p>
*/
public float cutOffDistance = Float.POSITIVE_INFINITY;
/**
* fog's maximum opacity between 0 and 1. Ignored in `linearFog` mode.
* fog's maximum opacity between 0 and 1. Ignored in <code>linearFog</code> mode.
*/
public float maximumOpacity = 1.0f;
/**
@@ -1631,11 +1628,11 @@ public class View {
* It can be expressed as 1/H, where H is the altitude change in world units [m] that causes a
* factor 2.78 (e) change in fog density.
*
* A falloff of 0 means the fog density is constant everywhere and may result is slightly
* faster computations.
* <p>A falloff of 0 means the fog density is constant everywhere and may result is slightly
* faster computations.</p>
*
* In `linearFog` mode, only use to compute the slope of the linear equation. Completely
* ignored if set to 0.
* <p>In <code>linearFog</code> mode, only use to compute the slope of the linear equation. Completely
* ignored if set to 0.</p>
*/
public float heightFalloff = 1.0f;
/**
@@ -1645,11 +1642,11 @@ public class View {
* above one are allowed but could create a non energy-conservative fog (this is dependant
* on the IBL's intensity as well).
*
* We assume that our fog has no absorption and therefore all the light it scatters out
* <p>We assume that our fog has no absorption and therefore all the light it scatters out
* becomes ambient light in-scattering and has lost all directionality, i.e.: scattering is
* isotropic. This somewhat simulates Rayleigh scattering.
* isotropic. This somewhat simulates Rayleigh scattering.</p>
*
* This value is used as a tint instead, when fogColorFromIbl is enabled.
* <p>This value is used as a tint instead, when fogColorFromIbl is enabled.</p>
*
* @see #fogColorFromIbl
*/
@@ -1660,20 +1657,20 @@ public class View {
* light is absorbed and out-scattered per unit of distance. Each unit of extinction reduces
* the incoming light to 37% of its original value.
*
* Note: The extinction factor is related to the fog density, it's usually some constant K times
* <p>Note: The extinction factor is related to the fog density, it's usually some constant K times
* the density at sea level (more specifically at fog height). The constant K depends on
* the composition of the fog/atmosphere.
* the composition of the fog/atmosphere.</p>
*
* For historical reason this parameter is called `density`.
* <p>For historical reason this parameter is called <code>density</code>.</p>
*
* In `linearFog` mode this is the slope of the linear equation if heightFalloff is set to 0.
* <p>In <code>linearFog</code> mode this is the slope of the linear equation if heightFalloff is set to 0.
* Otherwise, heightFalloff affects the slope calculation such that it matches the slope of
* the standard equation at the camera height.
* the standard equation at the camera height.</p>
*/
public float density = 0.1f;
/**
* Distance in world units [m] from the camera where the Sun in-scattering starts.
* Ignored in `linearFog` mode.
* Ignored in <code>linearFog</code> mode.
*/
public float inScatteringStart = 0.0f;
/**
@@ -1681,16 +1678,16 @@ public class View {
* is scattered (by the fog) towards the camera.
* Size of the Sun in-scattering (>0 to activate). Good values are >> 1 (e.g. ~10 - 100).
* Smaller values result is a larger scattering size.
* Ignored in `linearFog` mode.
* Ignored in <code>linearFog</code> mode.
*/
public float inScatteringSize = -1.0f;
/**
* The fog color will be sampled from the IBL in the view direction and tinted by `color`.
* The fog color will be sampled from the IBL in the view direction and tinted by <code>color</code>.
* Depending on the scene this can produce very convincing results.
*
* This simulates a more anisotropic phase-function.
* <p>This simulates a more anisotropic phase-function.</p>
*
* `fogColorFromIbl` is ignored when skyTexture is specified.
* <p><code>fogColorFromIbl</code> is ignored when skyTexture is specified.</p>
*
* @see #skyColor
*/
@@ -1703,11 +1700,11 @@ public class View {
* level with a strong gaussian filter or even an irradiance filter and then generate mip
* levels as usual. How blurred the base level is somewhat of an artistic decision.
*
* This simulates a more anisotropic phase-function.
* <p>This simulates a more anisotropic phase-function.</p>
*
* `fogColorFromIbl` is ignored when skyTexture is specified.
* <p><code>fogColorFromIbl</code> is ignored when skyTexture is specified.</p>
*
* In `linearFog` mode mipmap level 0 is always used.
* <p>In <code>linearFog</code> mode mipmap level 0 is always used.</p>
*
* @see Texture
* @see #fogColorFromIbl
@@ -1723,9 +1720,9 @@ public class View {
/**
* Options to control Depth of Field (DoF) effect in the scene.
*
* cocScale can be used to set the depth of field blur independently of the camera
* <p>cocScale can be used to set the depth of field blur independently of the camera
* aperture, e.g. for artistic reasons. This can be achieved by setting:
* cocScale = cameraAperture / desiredDoFAperture
* cocScale = cameraAperture / desiredDoFAperture</p>
*
* @see Camera
*/
@@ -1736,59 +1733,24 @@ public class View {
MEDIAN,
}
/**
* circle of confusion scale factor (amount of blur)
*/
/** circle of confusion scale factor (amount of blur) */
public float cocScale = 1.0f;
/**
* width/height aspect ratio of the circle of confusion (simulate anamorphic lenses)
*/
/** width/height aspect ratio of the circle of confusion (simulate anamorphic lenses) */
public float cocAspectRatio = 1.0f;
/**
* maximum aperture diameter in meters (zero to disable rotation)
*/
/** maximum aperture diameter in meters (zero to disable rotation) */
public float maxApertureDiameter = 0.01f;
/**
* enable or disable depth of field effect
*/
/** enable or disable depth of field effect */
public boolean enabled = false;
/**
* filter to use for filling gaps in the kernel
*/
/** filter to use for filling gaps in the kernel */
@NonNull
public DepthOfFieldOptions.Filter filter = DepthOfFieldOptions.Filter.MEDIAN;
/**
* perform DoF processing at native resolution
*/
/** perform DoF processing at native resolution */
public boolean nativeResolution = false;
/**
* Number of of rings used by the gather kernels. The number of rings affects quality
* and performance. The actual number of sample per pixel is defined
* as (ringCount * 2 - 1)^2. Here are a few commonly used values:
* 3 rings : 25 ( 5x 5 grid)
* 4 rings : 49 ( 7x 7 grid)
* 5 rings : 81 ( 9x 9 grid)
* 17 rings : 1089 (33x33 grid)
*
* With a maximum circle-of-confusion of 32, it is never necessary to use more than 17 rings.
*
* Usually all three settings below are set to the same value, however, it is often
* acceptable to use a lower ring count for the "fast tiles", which improves performance.
* Fast tiles are regions of the screen where every pixels have a similar
* circle-of-confusion radius.
*
* A value of 0 means default, which is 5 on desktop and 3 on mobile.
*
* @{
*/
/** number of kernel rings for foreground tiles */
public int foregroundRingCount = 0;
/**
* number of kernel rings for background tiles
*/
/** number of kernel rings for background tiles */
public int backgroundRingCount = 0;
/**
* number of kernel rings for fast tiles
*/
/** number of kernel rings for fast tiles */
public int fastGatherRingCount = 0;
/**
* maximum circle-of-confusion in pixels for the foreground, must be in [0, 32] range.
@@ -1806,26 +1768,16 @@ public class View {
* Options to control the vignetting effect.
*/
public static class VignetteOptions {
/**
* high values restrict the vignette closer to the corners, between 0 and 1
*/
/** high values restrict the vignette closer to the corners, between 0 and 1 */
public float midPoint = 0.5f;
/**
* controls the shape of the vignette, from a rounded rectangle (0.0), to an oval (0.5), to a circle (1.0)
*/
/** controls the shape of the vignette, from a rounded rectangle (0.0), to an oval (0.5), to a circle (1.0) */
public float roundness = 0.5f;
/**
* softening amount of the vignette effect, between 0 and 1
*/
/** softening amount of the vignette effect, between 0 and 1 */
public float feather = 0.5f;
/**
* color of the vignette effect, alpha is currently ignored
*/
/** color of the vignette effect, alpha is currently ignored */
@NonNull @Size(min = 4)
public float[] color = {0.0f, 0.0f, 0.0f, 1.0f};
/**
* enables or disables the vignette effect
*/
/** enables or disables the vignette effect */
public boolean enabled = false;
}
@@ -1839,11 +1791,11 @@ public class View {
/**
* Sets the quality of the HDR color buffer.
*
* A quality of HIGH or ULTRA means using an RGB16F or RGBA16F color buffer. This means
* <p>A quality of HIGH or ULTRA means using an RGB16F or RGBA16F color buffer. This means
* colors in the LDR range (0..1) have a 10 bit precision. A quality of LOW or MEDIUM means
* using an R11G11B10F opaque color buffer or an RGBA16F transparent color buffer. With
* R11G11B10F colors in the LDR range have a precision of either 6 bits (red and green
* channels) or 5 bits (blue channel).
* channels) or 5 bits (blue channel).</p>
*/
@NonNull
public QualityLevel hdrColorBuffer = QualityLevel.HIGH;
@@ -1855,72 +1807,44 @@ public class View {
*/
public static class AmbientOcclusionOptions {
public enum AmbientOcclusionType {
/**
* use Scalable Ambient Occlusion
*/
/** use Scalable Ambient Occlusion */
SAO,
/**
* use Ground Truth-Based Ambient Occlusion
*/
/** use Ground Truth-Based Ambient Occlusion */
GTAO,
}
/**
* Type of ambient occlusion algorithm.
*/
/** Type of ambient occlusion algorithm. */
@NonNull
public AmbientOcclusionOptions.AmbientOcclusionType aoType = AmbientOcclusionOptions.AmbientOcclusionType.SAO;
/**
* Ambient Occlusion radius in meters, between 0 and ~10.
*/
/** Ambient Occlusion radius in meters, between 0 and ~10. */
public float radius = 0.3f;
/**
* Controls ambient occlusion's contrast. Must be positive.
*/
/** Controls ambient occlusion's contrast. Must be positive. */
public float power = 1.0f;
/**
* Self-occlusion bias in meters. Use to avoid self-occlusion.
* Between 0 and a few mm. No effect when aoType set to GTAO
*/
public float bias = 0.0005f;
/**
* How each dimension of the AO buffer is scaled. Must be either 0.5 or 1.0.
*/
/** How each dimension of the AO buffer is scaled. Must be either 0.5 or 1.0. */
public float resolution = 0.5f;
/**
* Strength of the Ambient Occlusion effect.
*/
/** Strength of the Ambient Occlusion effect. */
public float intensity = 1.0f;
/**
* depth distance that constitute an edge for filtering
*/
/** depth distance that constitute an edge for filtering */
public float bilateralThreshold = 0.05f;
/**
* affects # of samples used for AO and params for filtering
*/
/** affects # of samples used for AO and params for filtering */
@NonNull
public QualityLevel quality = QualityLevel.LOW;
/**
* affects AO smoothness. Recommend setting to HIGH when aoType set to GTAO.
*/
/** affects AO smoothness. Recommend setting to HIGH when aoType set to GTAO. */
@NonNull
public QualityLevel lowPassFilter = QualityLevel.MEDIUM;
/**
* affects AO buffer upsampling quality
*/
/** affects AO buffer upsampling quality */
@NonNull
public QualityLevel upsampling = QualityLevel.LOW;
/**
* enables or disables screen-space ambient occlusion
*/
/** enables or disables screen-space ambient occlusion */
public boolean enabled = false;
/**
* enables bent normals computation from AO, and specular AO
*/
/** enables bent normals computation from AO, and specular AO */
public boolean bentNormals = false;
/**
* min angle in radian to consider. No effect when aoType set to GTAO.
*/
/** min angle in radian to consider. No effect when aoType set to GTAO. */
public float minHorizonAngleRad = 0.0f;
/**
* Screen Space Cone Tracing (SSCT) options
@@ -2006,12 +1930,10 @@ public class View {
* @see #setMultiSampleAntiAliasingOptions
*/
public static class MultiSampleAntiAliasingOptions {
/**
* enables or disables msaa
*/
/** enables or disables msaa */
public boolean enabled = false;
/**
* sampleCount number of samples to use for multi-sampled anti-aliasing.\n
* sampleCount number of samples to use for multi-sampled anti-aliasing.<br>
* 0: treated as 1
* 1: no anti-aliasing
* n: sample count. Effective sample could be different depending on the
@@ -2030,106 +1952,75 @@ public class View {
* shaders to be recompiled. These options should be changed or set during initialization.
* `filterWidth`, `feedback` and `jitterPattern`, however, can be changed at any time.
*
* `feedback` of 0.1 effectively accumulates a maximum of 19 samples in steady state.
* see "A Survey of Temporal Antialiasing Techniques" by Lei Yang and all for more information.
* <p><code>feedback</code> of 0.1 effectively accumulates a maximum of 19 samples in steady state.
* see "A Survey of Temporal Antialiasing Techniques" by Lei Yang and all for more information.</p>
*
* @see #setTemporalAntiAliasingOptions
*/
public static class TemporalAntiAliasingOptions {
public enum BoxType {
/**
* use an AABB neighborhood
*/
/** use an AABB neighborhood */
AABB,
/**
* use the variance of the neighborhood (not recommended)
*/
VARIANCE,
/**
* use both AABB and variance
*/
/** use both AABB and variance */
AABB_VARIANCE,
}
public enum BoxClipping {
/**
* Accurate box clipping
*/
/** Accurate box clipping */
ACCURATE,
/**
* clamping
*/
/** clamping */
CLAMP,
/**
* no rejections (use for debugging)
*/
/** no rejections (use for debugging) */
NONE,
}
public enum JitterPattern {
/** 4-samples, rotated grid sampling */
RGSS_X4,
/** 4-samples, uniform grid in helix sequence */
UNIFORM_HELIX_X4,
/** 8-samples of halton 2,3 */
HALTON_23_X8,
/** 16-samples of halton 2,3 */
HALTON_23_X16,
/** 32-samples of halton 2,3 */
HALTON_23_X32,
}
/**
* reconstruction filter width typically between 1 (sharper) and 2 (smoother)
*/
/** @deprecated has no effect. */
public float filterWidth = 1.0f;
/**
* history feedback, between 0 (maximum temporal AA) and 1 (no temporal AA).
*/
/** history feedback, between 0 (maximum temporal AA) and 1 (no temporal AA). */
public float feedback = 0.12f;
/**
* texturing lod bias (typically -1 or -2)
*/
/** texturing lod bias (typically -1 or -2) */
public float lodBias = -1.0f;
/**
* post-TAA sharpen, especially useful when upscaling is true.
*/
/** post-TAA sharpen, especially useful when upscaling is true. */
public float sharpness = 0.0f;
/**
* enables or disables temporal anti-aliasing
*/
/** enables or disables temporal anti-aliasing */
public boolean enabled = false;
/**
* 4x TAA upscaling. Disables Dynamic Resolution. [BETA]
*/
public boolean upscaling = false;
/**
* whether to filter the history buffer
*/
/** Upscaling factor. Disables Dynamic Resolution. [BETA] */
public float upscaling = 1.0f;
/** whether to filter the history buffer */
public boolean filterHistory = true;
/**
* whether to apply the reconstruction filter to the input
*/
/** whether to apply the reconstruction filter to the input */
public boolean filterInput = true;
/**
* whether to use the YcoCg color-space for history rejection
*/
/** whether to use the YcoCg color-space for history rejection */
public boolean useYCoCg = false;
/**
* type of color gamut box
*/
/** set to true for HDR content */
public boolean hdr = true;
/** type of color gamut box */
@NonNull
public TemporalAntiAliasingOptions.BoxType boxType = TemporalAntiAliasingOptions.BoxType.AABB;
/**
* clipping algorithm
*/
/** clipping algorithm */
@NonNull
public TemporalAntiAliasingOptions.BoxClipping boxClipping = TemporalAntiAliasingOptions.BoxClipping.ACCURATE;
/** Jitter Pattern */
@NonNull
public TemporalAntiAliasingOptions.JitterPattern jitterPattern = TemporalAntiAliasingOptions.JitterPattern.HALTON_23_X16;
/** High values increases ghosting artefact, lower values increases jittering, range [0.75, 1.25] */
public float varianceGamma = 1.0f;
/**
* adjust the feedback dynamically to reduce flickering
*/
/** adjust the feedback dynamically to reduce flickering */
public boolean preventFlickering = false;
/**
* whether to apply history reprojection (debug option)
*/
/** whether to apply history reprojection (debug option) */
public boolean historyReprojection = true;
}
@@ -2138,30 +2029,22 @@ public class View {
* @see #setScreenSpaceReflectionsOptions
*/
public static class ScreenSpaceReflectionsOptions {
/**
* ray thickness, in world units
*/
/** ray thickness, in world units */
public float thickness = 0.1f;
/**
* bias, in world units, to prevent self-intersections
*/
/** bias, in world units, to prevent self-intersections */
public float bias = 0.01f;
/**
* maximum distance, in world units, to raycast
*/
/** maximum distance, in world units, to raycast */
public float maxDistance = 3.0f;
/**
* stride, in texels, for samples along the ray.
*/
/** stride, in texels, for samples along the ray. */
public float stride = 2.0f;
public boolean enabled = false;
}
/**
* Options for the screen-space guard band.
* A guard band can be enabled to avoid some artifacts towards the edge of the screen when
* <p>A guard band can be enabled to avoid some artifacts towards the edge of the screen when
* using screen-space effects such as SSAO. Enabling the guard band reduces performance slightly.
* Currently the guard band can only be enabled or disabled.
* Currently the guard band can only be enabled or disabled.</p>
*/
public static class GuardBandOptions {
public boolean enabled = false;
@@ -2174,13 +2057,9 @@ public class View {
* @see #setSampleCount
*/
public enum AntiAliasing {
/**
* no anti aliasing performed as part of post-processing
*/
/** no anti aliasing performed as part of post-processing */
NONE,
/**
* FXAA is a low-quality but very efficient type of anti-aliasing. (default).
*/
/** FXAA is a low-quality but very efficient type of anti-aliasing. (default). */
FXAA,
}
@@ -2188,13 +2067,9 @@ public class View {
* List of available post-processing dithering techniques.
*/
public enum Dithering {
/**
* No dithering
*/
/** No dithering */
NONE,
/**
* Temporal dithering (default)
*/
/** Temporal dithering (default) */
TEMPORAL,
}
@@ -2203,21 +2078,13 @@ public class View {
* @see #setShadowType
*/
public enum ShadowType {
/**
* percentage-closer filtered shadows (default)
*/
/** percentage-closer filtered shadows (default) */
PCF,
/**
* variance shadows
*/
/** variance shadows */
VSM,
/**
* PCF with contact hardening simulation
*/
/** PCF with contact hardening simulation */
DPCF,
/**
* PCF with soft shadows and contact hardening
*/
/** PCF with soft shadows and contact hardening */
PCSS,
PCFd,
}
@@ -2225,14 +2092,14 @@ public class View {
/**
* View-level options for VSM Shadowing.
* @see #setVsmShadowOptions
* @warning This API is still experimental and subject to change.
* <b>Warning:</b> This API is still experimental and subject to change.
*/
public static class VsmShadowOptions {
/**
* Sets the number of anisotropic samples to use when sampling a VSM shadow map. If greater
* than 0, mipmaps will automatically be generated each frame for all lights.
*
* The number of anisotropic samples = 2 ^ vsmAnisotropy.
* <p>The number of anisotropic samples = 2 ^ vsmAnisotropy.</p>
*/
public int anisotropy = 0;
/**
@@ -2254,7 +2121,7 @@ public class View {
*/
public boolean highPrecision = false;
/**
* VSM minimum variance scale, must be positive.
* @deprecated has no effect.
*/
public float minVarianceScale = 0.5f;
/**
@@ -2266,7 +2133,7 @@ public class View {
/**
* View-level options for DPCF and PCSS Shadowing.
* @see #setSoftShadowOptions
* @warning This API is still experimental and subject to change.
* <b>Warning:</b> This API is still experimental and subject to change.
*/
public static class SoftShadowOptions {
/**

12
android/filament-tools/.gitignore vendored Normal file
View File

@@ -0,0 +1,12 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
/.idea/caches
/.idea/gradle.xml
.DS_Store
/build
/captures
.externalNativeBuild
/.cxx

View File

@@ -0,0 +1,64 @@
plugins {
id "de.undercouch.download" version "5.6.0"
}
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
def tools = ['matc', 'cmgen']
def platforms = [
'mac': [classifier: 'osx-aarch_64', archive: "filament-v${VERSION_NAME}-mac.tgz", path: { t -> "filament/bin/${t}" }],
'linux': [classifier: 'linux-x86_64', archive: "filament-v${VERSION_NAME}-linux.tgz", path: { t -> "filament/bin/${t}" }],
'windows': [classifier: 'windows-x86_64', archive: "filament-v${VERSION_NAME}-windows.tgz", path: { t -> "bin/${t}.exe" }]
]
platforms.each { platform, config ->
def platformName = platform.capitalize()
def remoteUrl = "https://github.com/google/filament/releases/download/v${VERSION_NAME}/${config.archive}"
def downloadFile = file("${buildDir}/downloads/${config.archive}")
def extractDir = file("${buildDir}/extracted/filament-v${VERSION_NAME}-${platform}")
task "downloadRelease${platformName}"(type: Download) {
src remoteUrl
dest downloadFile
overwrite false
}
def extractionTask = task "extractTools${platformName}"(dependsOn: "downloadRelease${platformName}", type: Copy) {
group = "setup"
from tarTree(resources.gzip(downloadFile))
// Include specific tools based on platform pattern
include tools.collect { tool -> config.path(tool) }
// Flatten the path so it lands directly in 'into'
eachFile { fcd ->
fcd.relativePath = new RelativePath(true, fcd.name)
}
into extractDir
includeEmptyDirs = false
}
}
publishing {
publications {
tools.each { toolName ->
create(toolName, MavenPublication) {
artifactId = toolName
platforms.each { platform, config ->
def extractDir = file("${buildDir}/extracted/filament-v${VERSION_NAME}-${platform}")
def archivePath = config.path(toolName)
def exeName = new File(archivePath).name
artifact(new File(extractDir, exeName)) {
classifier = config.classifier
extension = "exe"
builtBy tasks.named("extractTools${platform.capitalize()}")
}
}
}
}
}
}

View File

@@ -0,0 +1,2 @@
POM_NAME=Filament
POM_PACKAGING=exe

View File

@@ -22,6 +22,10 @@ add_library(image STATIC IMPORTED)
set_target_properties(image PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libimage.a)
add_library(imageio-lite STATIC IMPORTED)
set_target_properties(imageio-lite PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libimageio-lite.a)
add_library(ktxreader STATIC IMPORTED)
set_target_properties(ktxreader PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libktxreader.a)
@@ -30,6 +34,10 @@ add_library(viewer STATIC IMPORTED)
set_target_properties(viewer PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libviewer.a)
add_library(imagediff STATIC IMPORTED)
set_target_properties(imagediff PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libimagediff.a)
add_library(civetweb STATIC IMPORTED)
set_target_properties(civetweb PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libcivetweb.a)
@@ -57,6 +65,7 @@ add_library(filament-utils-jni SHARED
src/main/cpp/IBLPrefilterContext.cpp
src/main/cpp/Utils.cpp
src/main/cpp/Manipulator.cpp
src/main/cpp/ImageDiff.cpp
src/main/cpp/RemoteServer.cpp
${IMAGEIO_DIR}/include/imageio/ImageDecoder.h
@@ -74,6 +83,7 @@ target_include_directories(filament-utils-jni PRIVATE
${FILAMENT_DIR}/include
../../filament/backend/include
${IMAGEIO_DIR}/include
../../libs/imagediff/include
../../libs/utils/include)
set_target_properties(filament-utils-jni PROPERTIES LINK_DEPENDS ${VERSION_SCRIPT})
@@ -85,10 +95,13 @@ target_link_libraries(filament-utils-jni
PRIVATE camutils
PRIVATE iblprefilter
PRIVATE image
PRIVATE imageio-lite
PRIVATE filament-jni
PRIVATE ktxreader
PRIVATE viewer
PRIVATE imagediff
PRIVATE log
PRIVATE utils
PRIVATE perfetto # needed only when FILAMENT_ENABLE_PERFETTO is defined
PRIVATE jnigraphics # needed for AndroidBitmap_* functions in ImageDiff
)

View File

@@ -71,8 +71,10 @@ Java_com_google_android_filament_utils_AutomationEngine_nStartBatchMode(JNIEnv*
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclass klass,
jlong nativeAutomation, jlong nativeEngine,
jlong view, jlongArray materials, jlong renderer, jfloat deltaTime) {
jlong view, jlongArray materials, jlong renderer, jlong nativeIbl, jint sunlightEntity,
jintArray assetLights, jlong nativeLm, jlong scene, jfloat deltaTime) {
using MaterialPointer = MaterialInstance*;
jsize materialCount = 0;
jlong* longMaterials = nullptr;
MaterialPointer* ptrMaterials = nullptr;
@@ -84,12 +86,28 @@ Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclas
ptrMaterials[i] = (MaterialPointer) longMaterials[i];
}
}
jsize lightCount = 0;
jint* intLights = nullptr;
if (assetLights) {
lightCount = env->GetArrayLength(assetLights);
intLights = env->GetIntArrayElements(assetLights, nullptr);
}
static_assert(sizeof(jint) == sizeof(Entity));
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
AutomationEngine::ViewerContent content = {
.view = (View*) view,
.renderer = (Renderer*) renderer,
.materials = ptrMaterials,
.materialCount = (size_t) materialCount,
.lightManager = (LightManager*) nativeLm,
.scene = (Scene*) scene,
.indirectLight = (IndirectLight*) nativeIbl,
.sunlight = (Entity&) sunlightEntity,
.assetLights = (Entity*) intLights,
.assetLightCount = (size_t) lightCount,
};
Engine* engine = (Engine*)nativeEngine;
automation->tick(engine, content, deltaTime);
@@ -97,6 +115,9 @@ Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclas
env->ReleaseLongArrayElements(materials, longMaterials, 0);
delete[] ptrMaterials;
}
if (intLights) {
env->ReleaseIntArrayElements(assetLights, intLights, 0);
}
}
extern "C" JNIEXPORT void JNICALL
@@ -159,37 +180,50 @@ extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nGetViewerOptions(JNIEnv* env, jclass,
jlong nativeObject, jobject result) {
AutomationEngine* automation = (AutomationEngine*) nativeObject;
auto options = automation->getViewerOptions();
const auto& settings = automation->getSettings();
const auto& options = settings.viewer;
const jclass klass = env->GetObjectClass(result);
const jfieldID cameraAperture = env->GetFieldID(klass, "cameraAperture", "F");
const jfieldID cameraSpeed = env->GetFieldID(klass, "cameraSpeed", "F");
const jfieldID cameraISO = env->GetFieldID(klass, "cameraISO", "F");
const jfieldID cameraNear = env->GetFieldID(klass, "cameraNear", "F");
const jfieldID cameraFar = env->GetFieldID(klass, "cameraFar", "F");
const jfieldID groundShadowStrength = env->GetFieldID(klass, "groundShadowStrength", "F");
const jfieldID groundPlaneEnabled = env->GetFieldID(klass, "groundPlaneEnabled", "Z");
const jfieldID skyboxEnabled = env->GetFieldID(klass, "skyboxEnabled", "Z");
const jfieldID cameraFocalLength = env->GetFieldID(klass, "cameraFocalLength", "F");
const jfieldID cameraFocusDistance = env->GetFieldID(klass, "cameraFocusDistance", "F");
const jfieldID autoScaleEnabled = env->GetFieldID(klass, "autoScaleEnabled", "Z");
const jfieldID autoInstancingEnabled = env->GetFieldID(klass, "autoInstancingEnabled", "Z");
env->SetFloatField(result, cameraAperture, options.cameraAperture);
env->SetFloatField(result, cameraSpeed, options.cameraSpeed);
env->SetFloatField(result, cameraISO, options.cameraISO);
env->SetFloatField(result, cameraNear, options.cameraNear);
env->SetFloatField(result, cameraFar, options.cameraFar);
env->SetFloatField(result, groundShadowStrength, options.groundShadowStrength);
env->SetBooleanField(result, groundPlaneEnabled, options.groundPlaneEnabled);
env->SetBooleanField(result, skyboxEnabled, options.skyboxEnabled);
env->SetFloatField(result, cameraFocalLength, options.cameraFocalLength);
env->SetFloatField(result, cameraFocusDistance, options.cameraFocusDistance);
env->SetBooleanField(result, autoScaleEnabled, options.autoScaleEnabled);
env->SetBooleanField(result, autoInstancingEnabled, options.autoInstancingEnabled);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nGetCameraSettings(JNIEnv* env, jclass,
jlong nativeObject, jobject result) {
AutomationEngine* automation = (AutomationEngine*) nativeObject;
const auto& settings = automation->getSettings();
const auto& camera = settings.camera;
const jclass klass = env->GetObjectClass(result);
const jfieldID aperture = env->GetFieldID(klass, "aperture", "F");
const jfieldID shutterSpeed = env->GetFieldID(klass, "shutterSpeed", "F");
const jfieldID sensitivity = env->GetFieldID(klass, "sensitivity", "F");
const jfieldID near = env->GetFieldID(klass, "near", "F");
const jfieldID far = env->GetFieldID(klass, "far", "F");
const jfieldID focalLength = env->GetFieldID(klass, "focalLength", "F");
const jfieldID focusDistance = env->GetFieldID(klass, "focusDistance", "F");
env->SetFloatField(result, aperture, camera.aperture);
env->SetFloatField(result, shutterSpeed, camera.shutterSpeed);
env->SetFloatField(result, sensitivity, camera.sensitivity);
env->SetFloatField(result, near, camera.near);
env->SetFloatField(result, far, camera.far);
env->SetFloatField(result, focalLength, camera.focalLength);
env->SetFloatField(result, focusDistance, camera.focusDistance);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nGetColorGrading(JNIEnv*, jclass,
jlong nativeObject, jlong nativeEngine) {
@@ -215,6 +249,18 @@ Java_com_google_android_filament_utils_AutomationEngine_nShouldClose(JNIEnv*, jc
return automation->shouldClose();
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nGetTestCount(JNIEnv*, jclass, jlong native) {
AutomationEngine* automation = (AutomationEngine*) native;
return (jint) automation->testCount();
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nGetCurrentTest(JNIEnv*, jclass, jlong native) {
AutomationEngine* automation = (AutomationEngine*) native;
return (jint) automation->currentTest();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nDestroy(JNIEnv*, jclass, jlong native) {
AutomationEngine* automation = (AutomationEngine*) native;

View File

@@ -0,0 +1,217 @@
/*
* Copyright (C) 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <jni.h>
#include <android/bitmap.h>
#include <imagediff/ImageDiff.h>
#include <utils/Log.h>
#include <vector>
using namespace imagediff;
using namespace utils;
namespace {
struct BitmapLock {
JNIEnv* env;
jobject bitmap;
void* pixels;
AndroidBitmapInfo info;
BitmapLock(JNIEnv* env, jobject bitmap) : env(env), bitmap(bitmap), pixels(nullptr) {
if (!bitmap) return;
if (AndroidBitmap_getInfo(env, bitmap, &info) < 0) {
return;
}
if (AndroidBitmap_lockPixels(env, bitmap, &pixels) < 0) {
pixels = nullptr;
}
}
~BitmapLock() {
if (pixels) {
AndroidBitmap_unlockPixels(env, bitmap);
}
}
bool isValid() const { return pixels != nullptr; }
imagediff::Bitmap toBitmap() const {
return {
.width = (uint32_t) info.width,
.height = (uint32_t) info.height,
.stride = (size_t) info.stride,
.data = pixels
};
}
};
} // namespace
// Helper to convert C++ ImageDiffResult to Java Result
jobject createResult(JNIEnv* env, ImageDiffResult const& result, bool generateDiff) {
// Create Result class/objects
jclass resultClass = env->FindClass("com/google/android/filament/utils/ImageDiff$Result");
jmethodID resultCtor = env->GetMethodID(resultClass, "<init>", "()V");
jobject resultObj = env->NewObject(resultClass, resultCtor);
jfieldID statusField = env->GetFieldID(resultClass, "status", "Lcom/google/android/filament/utils/ImageDiff$Result$Status;");
jfieldID failingCountField = env->GetFieldID(resultClass, "failingPixelCount", "J");
jfieldID maxDiffField = env->GetFieldID(resultClass, "maxDiffFound", "[F");
jfieldID diffImageField = env->GetFieldID(resultClass, "diffImage", "Landroid/graphics/Bitmap;");
// Map Status enum
jclass statusEnum = env->FindClass("com/google/android/filament/utils/ImageDiff$Result$Status");
jobject statusObj = nullptr;
jfieldID enumField = nullptr;
switch (result.status) {
case ImageDiffResult::Status::PASSED:
enumField = env->GetStaticFieldID(statusEnum, "PASSED", "Lcom/google/android/filament/utils/ImageDiff$Result$Status;");
break;
case ImageDiffResult::Status::SIZE_MISMATCH:
enumField = env->GetStaticFieldID(statusEnum, "SIZE_MISMATCH", "Lcom/google/android/filament/utils/ImageDiff$Result$Status;");
break;
case ImageDiffResult::Status::PIXEL_DIFFERENCE:
enumField = env->GetStaticFieldID(statusEnum, "PIXEL_DIFFERENCE", "Lcom/google/android/filament/utils/ImageDiff$Result$Status;");
break;
}
statusObj = env->GetStaticObjectField(statusEnum, enumField);
env->SetObjectField(resultObj, statusField, statusObj);
env->SetLongField(resultObj, failingCountField, (jlong) result.failingPixelCount);
jfloatArray maxDiffArray = env->NewFloatArray(4);
env->SetFloatArrayRegion(maxDiffArray, 0, 4, result.maxDiffFound);
env->SetObjectField(resultObj, maxDiffField, maxDiffArray);
if (generateDiff && result.diffImage.getWidth() > 0) {
jclass bitmapClass = env->FindClass("android/graphics/Bitmap");
jmethodID createBitmap = env->GetStaticMethodID(bitmapClass, "createBitmap",
"(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
jclass configClass = env->FindClass("android/graphics/Bitmap$Config");
jfieldID argb8888 = env->GetStaticFieldID(configClass, "ARGB_8888", "Landroid/graphics/Bitmap$Config;");
jobject configObj = env->GetStaticObjectField(configClass, argb8888);
uint32_t width = result.diffImage.getWidth();
uint32_t height = result.diffImage.getHeight();
jobject diffBitmap = env->CallStaticObjectMethod(bitmapClass, createBitmap, (jint)width, (jint)height, configObj);
if (diffBitmap) {
void* diffPixels;
if (AndroidBitmap_lockPixels(env, diffBitmap, &diffPixels) == 0) {
float const* src = result.diffImage.getPixelRef();
uint8_t* dst = (uint8_t*) diffPixels;
uint32_t channels = result.diffImage.getChannels(); // usually 4
for (size_t i = 0; i < width * height; ++i) {
for (int c = 0; c < 4; ++c) {
float v = 0.0f;
if (c < channels) v = src[i * channels + c];
if (c == 3 && channels < 4) v = 1.0f; // Alpha 1.0 if missing
dst[i * 4 + c] = (uint8_t) std::min(255.0f, std::max(0.0f, v * 255.0f));
}
}
AndroidBitmap_unlockPixels(env, diffBitmap);
env->SetObjectField(resultObj, diffImageField, diffBitmap);
}
}
}
return resultObj;
}
extern "C" JNIEXPORT jobject JNICALL
Java_com_google_android_filament_utils_ImageDiff_nCompareBasic(JNIEnv* env, jclass,
jobject refBitmap, jobject candBitmap, jint mode, jint swizzle, jint channelMask,
jfloat maxAbsDiff, jfloat maxFailingPixelsFraction, jobject maskBitmap) {
BitmapLock refArg(env, refBitmap);
BitmapLock candArg(env, candBitmap);
BitmapLock maskArg(env, maskBitmap);
if (!refArg.isValid() || !candArg.isValid()) {
ImageDiffResult emptyResult;
emptyResult.status = ImageDiffResult::Status::SIZE_MISMATCH; // or ERROR
return createResult(env, emptyResult, false);
}
ImageDiffConfig config;
config.mode = (ImageDiffConfig::Mode) mode;
config.swizzle = (ImageDiffConfig::Swizzle) swizzle;
config.channelMask = (uint8_t) channelMask;
config.maxAbsDiff = maxAbsDiff;
config.maxFailingPixelsFraction = maxFailingPixelsFraction;
imagediff::Bitmap const* maskPtr = nullptr;
imagediff::Bitmap maskVal;
if (maskBitmap && maskArg.isValid()) {
maskVal = maskArg.toBitmap();
maskPtr = &maskVal;
}
bool generateDiff = true;
ImageDiffResult result = compare(refArg.toBitmap(), candArg.toBitmap(), config, maskPtr, generateDiff);
return createResult(env, result, generateDiff);
}
extern "C" JNIEXPORT jobject JNICALL
Java_com_google_android_filament_utils_ImageDiff_nCompareJson(JNIEnv* env, jclass,
jobject refBitmap, jobject candBitmap, jstring jsonConfig, jobject maskBitmap) {
BitmapLock refArg(env, refBitmap);
BitmapLock candArg(env, candBitmap);
BitmapLock maskArg(env, maskBitmap);
if (!refArg.isValid() || !candArg.isValid()) {
ImageDiffResult emptyResult;
emptyResult.status = ImageDiffResult::Status::SIZE_MISMATCH; // or ERROR
return createResult(env, emptyResult, false);
}
ImageDiffConfig config;
const char* nativeJson = env->GetStringUTFChars(jsonConfig, 0);
size_t length = env->GetStringUTFLength(jsonConfig);
bool parsed = parseConfig(nativeJson, length, &config);
env->ReleaseStringUTFChars(jsonConfig, nativeJson);
if (!parsed) {
// Fallback to default or error?
// We could log error.
utils::slog.e << "ImageDiff JNI: Failed to parse JSON config" << utils::io::endl;
ImageDiffResult errResult;
errResult.status = ImageDiffResult::Status::PIXEL_DIFFERENCE; // assume fail
return createResult(env, errResult, false);
}
imagediff::Bitmap const* maskPtr = nullptr;
imagediff::Bitmap maskVal;
if (maskBitmap && maskArg.isValid()) {
maskVal = maskArg.toBitmap();
maskPtr = &maskVal;
}
bool generateDiff = true;
ImageDiffResult result = compare(refArg.toBitmap(), candArg.toBitmap(), config, maskPtr, generateDiff);
return createResult(env, result, generateDiff);
}

View File

@@ -94,20 +94,23 @@ public class AutomationEngine {
* Allows remote control for the viewer.
*/
public static class ViewerOptions {
public float cameraAperture = 16.0f;
public float cameraSpeed = 125.0f;
public float cameraISO = 100.0f;
public float cameraNear = 0.1f;
public float cameraFar = 100.0f;
public float groundShadowStrength = 0.75f;
public boolean groundPlaneEnabled = false;
public boolean skyboxEnabled = true;
public float cameraFocalLength = 28.0f;
public float cameraFocusDistance = 0.0f;
public boolean autoScaleEnabled = true;
public boolean autoInstancingEnabled = false;
}
public static class CameraSettings {
public float aperture = 16.0f;
public float shutterSpeed = 125.0f;
public float sensitivity = 100.0f;
public float near = 0.1f;
public float far = 100.0f;
public float focalLength = 28.0f;
public float focusDistance = 10.0f;
}
/**
* Creates an automation engine from a JSON specification.
*
@@ -175,7 +178,12 @@ public class AutomationEngine {
}
long nativeView = content.view.getNativeObject();
long nativeRenderer = content.renderer.getNativeObject();
nTick(mNativeObject, engine.getNativeObject(), nativeView, nativeMaterialInstances, nativeRenderer, deltaTime);
long nativeIbl = content.indirectLight == null ? 0 : content.indirectLight.getNativeObject();
long nativeLm = content.lightManager == null ? 0 : content.lightManager.getNativeObject();
long nativeScene = content.scene == null ? 0 : content.scene.getNativeObject();
nTick(mNativeObject, engine.getNativeObject(), nativeView, nativeMaterialInstances,
nativeRenderer, nativeIbl, content.sunlight, content.assetLights, nativeLm,
nativeScene, deltaTime);
}
/**
@@ -229,6 +237,13 @@ public class AutomationEngine {
return result;
}
@NonNull
public CameraSettings getCameraSettings() {
CameraSettings result = new CameraSettings();
nGetCameraSettings(mNativeObject, result);
return result;
}
/**
* Gets a color grading object that corresponds to the latest settings.
*
@@ -261,6 +276,9 @@ public class AutomationEngine {
*/
public boolean shouldClose() { return nShouldClose(mNativeObject); }
public int getTestCount() { return nGetTestCount(mNativeObject); }
public int getCurrentTest() { return nGetCurrentTest(mNativeObject); }
@Override
protected void finalize() throws Throwable {
nDestroy(mNativeObject);
@@ -274,15 +292,19 @@ public class AutomationEngine {
private static native void nStartRunning(long nativeObject);
private static native void nStartBatchMode(long nativeObject);
private static native void nTick(long nativeObject, long nativeEngine,
long view, long[] materials, long renderer, float deltaTime);
long view, long[] materials, long renderer, long ibl, int sunlight, int[] assetLights,
long lightManager, long scene, float deltaTime);
private static native void nApplySettings(long nativeObject, long nativeEngine,
String jsonSettings, long view,
long[] materials, long ibl, int sunlight, int[] assetLights, long lightManager,
long scene, long renderer);
private static native void nGetViewerOptions(long nativeObject, Object result);
private static native void nGetCameraSettings(long nativeObject, Object result);
private static native long nGetColorGrading(long nativeObject, long nativeEngine);
private static native void nSignalBatchMode(long nativeObject);
private static native void nStopRunning(long nativeObject);
private static native boolean nShouldClose(long nativeObject);
private static native int nGetTestCount(long nativeObject);
private static native int nGetCurrentTest(long nativeObject);
private static native void nDestroy(long nativeObject);
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright (C) 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.utils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.graphics.Bitmap;
public class ImageDiff {
public enum Mode {
LEAF, AND, OR
}
public enum Swizzle {
RGBA, BGRA
}
public static class Config {
@NonNull
public Mode mode = Mode.LEAF;
@NonNull
public Swizzle swizzle = Swizzle.RGBA;
public int channelMask = 0xF;
public float maxAbsDiff = 0.0f;
public float maxFailingPixelsFraction = 0.0f;
// Children not supported in this simple wrapper for now, can be added if needed
}
public static class Result {
public enum Status {
PASSED,
SIZE_MISMATCH,
PIXEL_DIFFERENCE
}
public Status status;
public long failingPixelCount;
public float[] maxDiffFound; // [R, G, B, A]
public Bitmap diffImage; // Null if not generated
}
/**
* Compares two bitmaps using a configuration object.
*
* @param reference Golden image
* @param candidate Actual image
* @param config Comparison configuration
* @param mask Optional mask (grayscale)
* @return Result of comparison
*/
@NonNull
public static Result compareBasic(@NonNull Bitmap reference, @NonNull Bitmap candidate,
@NonNull Config config, @Nullable Bitmap mask) {
return nCompareBasic(reference, candidate, config.mode.ordinal(), config.swizzle.ordinal(),
config.channelMask, config.maxAbsDiff, config.maxFailingPixelsFraction, mask);
}
/**
* Compares two bitmaps using a JSON configuration string.
*
* @param reference Golden image
* @param candidate Actual image
* @param jsonConfig Comparison configuration in JSON format
* @param mask Optional mask (grayscale)
* @return Result of comparison
*/
@NonNull
public static Result compare(@NonNull Bitmap reference, @NonNull Bitmap candidate,
@NonNull String jsonConfig, @Nullable Bitmap mask) {
return nCompareJson(reference, candidate, jsonConfig, mask);
}
private static native Result nCompareBasic(Bitmap reference, Bitmap candidate, int mode, int swizzle,
int channelMask, float maxAbsDiff, float maxFailingPixelsFraction, Bitmap mask);
private static native Result nCompareJson(Bitmap reference, Bitmap candidate, String jsonConfig, Bitmap mask);
}

View File

@@ -16,6 +16,9 @@
package com.google.android.filament.utils
import android.graphics.Bitmap
import android.os.Handler
import android.os.Looper
import android.view.MotionEvent
import android.view.Surface
import android.view.SurfaceView
@@ -26,6 +29,7 @@ import com.google.android.filament.android.UiHelper
import com.google.android.filament.gltfio.*
import kotlinx.coroutines.*
import java.nio.Buffer
import java.nio.ByteBuffer
private const val kNearPlane = 0.05f // 5 cm
private const val kFarPlane = 1000.0f // 1 km
@@ -102,8 +106,8 @@ class ModelViewer(
var skyboxCubemap: Texture? = null
private lateinit var displayHelper: DisplayHelper
private lateinit var cameraManipulator: Manipulator
private lateinit var gestureDetector: GestureDetector
private var cameraManipulator: Manipulator? = null
private var gestureDetector: GestureDetector? = null
private var surfaceView: SurfaceView? = null
private var textureView: TextureView? = null
@@ -119,6 +123,8 @@ class ModelViewer(
private val target = DoubleArray(3)
private val upward = DoubleArray(3)
private var debugFrameCallback: ((Bitmap) -> Unit)? = null
init {
renderer = engine.createRenderer()
scene = engine.createScene()
@@ -151,15 +157,13 @@ class ModelViewer(
surfaceView: SurfaceView,
engine: Engine = Engine.create(),
uiHelper: UiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK),
manipulator: Manipulator? = null
manipulator: Manipulator? = defaultCameraManipulator(surfaceView.width, surfaceView.height)
) : this(engine, uiHelper) {
cameraManipulator = manipulator ?: Manipulator.Builder()
.targetPosition(kDefaultObjectPosition.x, kDefaultObjectPosition.y, kDefaultObjectPosition.z)
.viewport(surfaceView.width, surfaceView.height)
.build(Manipulator.Mode.ORBIT)
this.surfaceView = surfaceView
gestureDetector = GestureDetector(surfaceView, cameraManipulator)
cameraManipulator = manipulator
cameraManipulator?.let { c ->
gestureDetector = GestureDetector(surfaceView, c)
}
displayHelper = DisplayHelper(surfaceView.context)
uiHelper.renderCallback = SurfaceCallback()
uiHelper.attachTo(surfaceView)
@@ -171,15 +175,14 @@ class ModelViewer(
textureView: TextureView,
engine: Engine = Engine.create(),
uiHelper: UiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK),
manipulator: Manipulator? = null
manipulator: Manipulator? = defaultCameraManipulator(textureView.width, textureView.height)
) : this(engine, uiHelper) {
cameraManipulator = manipulator ?: Manipulator.Builder()
.targetPosition(kDefaultObjectPosition.x, kDefaultObjectPosition.y, kDefaultObjectPosition.z)
.viewport(textureView.width, textureView.height)
.build(Manipulator.Mode.ORBIT)
cameraManipulator = manipulator
this.textureView = textureView
gestureDetector = GestureDetector(textureView, cameraManipulator)
cameraManipulator = manipulator
cameraManipulator?.let { c ->
gestureDetector = GestureDetector(textureView, c)
}
displayHelper = DisplayHelper(textureView.context)
uiHelper.renderCallback = SurfaceCallback()
uiHelper.attachTo(textureView)
@@ -296,19 +299,50 @@ class ModelViewer(
asset?.let { populateScene(it) }
// Extract the camera basis from the helper and push it to the Filament camera.
cameraManipulator.getLookAt(eyePos, target, upward)
camera.lookAt(
cameraManipulator?.let { cm ->
cm.getLookAt(eyePos, target, upward)
camera.lookAt(
eyePos[0], eyePos[1], eyePos[2],
target[0], target[1], target[2],
upward[0], upward[1], upward[2])
}
// Render the scene, unless the renderer wants to skip the frame.
if (renderer.beginFrame(swapChain!!, frameTimeNanos)) {
renderer.render(view)
debugFrameCallback?.let {
val viewport = view.viewport
val bitmap = Bitmap.createBitmap(viewport.width, viewport.height,
Bitmap.Config.ARGB_8888)
val buffer = ByteBuffer.allocateDirect(viewport.width * viewport.height * 4)
val handler = Handler(Looper.getMainLooper())
val pixelBufferDescriptor = Texture.PixelBufferDescriptor(buffer,
Texture.Format.RGBA, Texture.Type.UBYTE, 1, 0, 0, 0, handler) {
buffer.rewind()
bitmap.copyPixelsFromBuffer(buffer)
it(bitmap)
}
renderer.readPixels(viewport.left, viewport.bottom, viewport.width,
viewport.height, pixelBufferDescriptor)
debugFrameCallback = null
}
renderer.endFrame()
}
}
/*
* Sets a callback that will be invoked with the next rendered frame as a Bitmap. Note that this
* is a one-time callback.
*
* @param callback callback to be invoked with a rendered frame as [Bitmap]
*/
fun debugGetNextFrameCallback(callback: (Bitmap) -> Unit) {
debugFrameCallback = callback
}
private fun populateScene(asset: FilamentAsset) {
val rcm = engine.renderableManager
var count = 0
@@ -363,7 +397,7 @@ class ModelViewer(
* Handles a [MotionEvent] to enable one-finger orbit, two-finger pan, and pinch-to-zoom.
*/
fun onTouchEvent(event: MotionEvent) {
gestureDetector.onTouchEvent(event)
gestureDetector?.onTouchEvent(event)
}
@SuppressWarnings("ClickableViewAccessibility")
@@ -416,7 +450,7 @@ class ModelViewer(
override fun onResized(width: Int, height: Int) {
view.viewport = Viewport(0, 0, width, height)
cameraManipulator.setViewport(width, height)
cameraManipulator?.setViewport(width, height)
updateCameraProjection()
synchronizePendingFrames(engine)
}
@@ -433,5 +467,11 @@ class ModelViewer(
companion object {
private val kDefaultObjectPosition = Float3(0.0f, 0.0f, -4.0f)
private fun defaultCameraManipulator(width: Int, height: Int) : Manipulator {
return Manipulator.Builder()
.targetPosition(kDefaultObjectPosition.x, kDefaultObjectPosition.y, kDefaultObjectPosition.z)
.viewport(width, height)
.build(Manipulator.Mode.ORBIT)
}
}
}

View File

@@ -6,6 +6,7 @@ option(FILAMENT_ENABLE_FGVIEWER "Enables Frame Graph Viewer" OFF)
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
option(FILAMENT_DISABLE_MATOPT "Disables material optimizations" OFF)
option(FILAMENT_SUPPORTS_WEBGPU "Enables WebGPU on Android" OFF)
option(FILAMENT_SUPPORTS_WEBP_TEXTURES "Enable webp texture support on Android" OFF)
set(CMAKE_CXX_STANDARD 20)
@@ -30,6 +31,12 @@ add_library(stb STATIC IMPORTED)
set_target_properties(stb PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libstb.a)
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
add_library(webpdecoder STATIC IMPORTED)
set_target_properties(webpdecoder PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libwebpdecoder.a)
endif()
add_library(basis_transcoder STATIC IMPORTED)
set_target_properties(basis_transcoder PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbasis_transcoder.a)
@@ -81,6 +88,10 @@ set(GLTFIO_INCLUDE_DIRS
../../libs/ktxreader/include
)
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
list(APPEND GLTFIO_INCLUDE_DIRS ../../third_party/libwebp/src)
endif()
add_library(gltfio-jni SHARED ${GLTFIO_SRCS})
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_DRACO_SUPPORTED=1)
@@ -107,3 +118,6 @@ target_link_libraries(gltfio-jni
PRIVATE perfetto # needed only when FILAMENT_ENABLE_PERFETTO is defined
PRIVATE log # needed only when perfetto above is used
)
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
target_link_libraries(gltfio-jni PRIVATE webpdecoder)
endif()

View File

@@ -128,6 +128,18 @@ Java_com_google_android_filament_gltfio_ResourceLoader_nCreateKtx2Provider(JNIEn
return (jlong) createKtx2Provider(engine);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nIsWebpSupported(JNIEnv*, jclass) {
return (jboolean) isWebpSupported();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nCreateWebpProvider(JNIEnv*, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) createWebpProvider(engine);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nDestroyTextureProvider(JNIEnv*, jclass,
jlong nativeProvider) {

View File

@@ -37,6 +37,7 @@ public class ResourceLoader {
private final long mNativeObject;
private final long mNativeStbProvider;
private final long mNativeKtx2Provider;
private final long mNativeWebpProvider;
/**
* Constructs a resource loader tied to the given Filament engine.
@@ -50,9 +51,17 @@ public class ResourceLoader {
mNativeObject = nCreateResourceLoader(nativeEngine, false);
mNativeStbProvider = nCreateStbProvider(nativeEngine);
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider);
if (nIsWebpSupported()) {
mNativeWebpProvider = nCreateWebpProvider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/webp", mNativeWebpProvider);
}
else {
mNativeWebpProvider = 0;
}
}
/**
@@ -68,9 +77,17 @@ public class ResourceLoader {
mNativeObject = nCreateResourceLoader(nativeEngine, normalizeSkinningWeights);
mNativeStbProvider = nCreateStbProvider(nativeEngine);
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider);
if (nIsWebpSupported()) {
mNativeWebpProvider = nCreateWebpProvider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/webp", mNativeWebpProvider);
}
else {
mNativeWebpProvider = 0;
}
}
/**
@@ -80,6 +97,9 @@ public class ResourceLoader {
nDestroyResourceLoader(mNativeObject);
nDestroyTextureProvider(mNativeStbProvider);
nDestroyTextureProvider(mNativeKtx2Provider);
if (nIsWebpSupported()) {
nDestroyTextureProvider(mNativeWebpProvider);
}
}
/**
@@ -191,6 +211,9 @@ public class ResourceLoader {
private static native long nCreateStbProvider(long nativeEngine);
private static native long nCreateKtx2Provider(long nativeEngine);
private static native boolean nIsWebpSupported();
private static native long nCreateWebpProvider(long nativeEngine);
private static native void nAddTextureProvider(long nativeLoader, String url, long nativeProvider);
private static native void nDestroyTextureProvider(long nativeProvider);
}

View File

@@ -0,0 +1,120 @@
# Filament Tools Gradle Plugin
## About
The **Filament Tools Gradle Plugin** helps integrate Filament into your Android project. It
automates the use of Filament's command-line tools (`matc`, `cmgen`, and `filamesh`).
This plugin handles:
- **Material Compilation**: Compiles `.mat` material definitions into `.filamat` binaries.
- **IBL Generation**: Generates Image-Based Lighting assets from HDR environment maps.
- **Mesh Compilation**: Converts models into Filament's efficient `.filamesh` binary format. *Note:
This tool is no longer recommended; instead, use glTF and Filament's `gltfio` library for model
loading.*
The plugin hooks directly into the Android build lifecycle (via `preBuild`) and supports incremental
builds, so assets are only recompiled when source files change.
## Usage
Apply the plugin in your module's `build.gradle` file and configure the `filament` block. You can
specify inputs and outputs for any combination of materials, IBLs, or meshes. If a path is not
configured, the corresponding task will be disabled.
### Example Configuration
```groovy
plugins {
id 'com.google.android.filament-tools'
}
filament {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
iblInputFile = project.layout.projectDirectory.file("path/to/environment.hdr")
iblOutputDir = project.layout.projectDirectory.dir("src/main/assets/envs")
meshInputFile = project.layout.projectDirectory.file("path/to/model.obj")
meshOutputDir = project.layout.projectDirectory.dir("src/main/assets/models")
}
```
### Configuration Details
- **materialInputDir**: The directory containing your source material definitions (`.mat` files).
- **materialOutputDir**: The directory where the compiled material files (`.filamat`) will be
generated.
- **iblInputFile**: The source high-dynamic-range image file (e.g., `.hdr` or `.exr`) used to
generate Image Based Lighting assets.
- **iblOutputDir**: The directory where the generated IBL assets (typically `.ktx` files) will be
placed.
- **meshInputFile**: The source mesh file (e.g., `.obj`) to be compiled.
- **meshOutputDir**: The directory where the compiled mesh file (`.filamesh`) will be generated.
Automatically adds tasks to your Android build to compile materials, generate an IBL, and compile a
mesh. The plugin hooks into `preBuild` to ensure assets are generated before the application is
built.
### Configuration Flags
You can control specific compilation options using Gradle properties (e.g., in `gradle.properties`
or via command line `-P`).
- **`com.google.android.filament.exclude-vulkan`** When set to `true`, the Vulkan backend is
excluded from the compiled materials. This can be useful to reduce the size of the generated
assets if your application does not target Vulkan. *Default: `false` (Vulkan is included)*
- **`com.google.android.filament.include-webgpu`** When set to `true`, the WebGPU backend is
included in the compiled materials. Use this if you intend to use the materials in a context
supporting WebGPU. *Default: `false`*
## Tools Configuration
The Filament Tools plugin requires some binary tools to be available: `matc`, `cmgen`, and
`filamesh`.
There are three ways to configure Filament tools:
1. **Point to a local path directly**
```groovy
filament {
matc {
path = "/path/to/matc"
}
cmgen {
path = "/path/to/cmgen"
}
filamesh {
path = "/path/to/filamesh"
}
}
```
2. **Point to a Maven artifact**
```groovy
filament {
matc {
// The minor version (the middle number) must match the Filament dependency's.
artifact = 'com.google.android.filament:matc:1.68.5'
}
cmgen {
artifact = 'com.google.android.filament:cmgen:1.68.5'
}
}
```
*Note that the `filamesh` artifact is not hosted on Maven Central, so it must be provided locally or
via another mechanism if needed.*
Gradle will automatically handle downloading the tool appropriate for your machine (MacOS/Linux/Windows) from Maven.
3. **Set the `com.google.android.filament.tools-dir` Gradle property**
This will override any other configuration. Gradle will attempt to locate the tools under
`<tools-dir>/bin` (e.g., `.../bin/matc`, `.../bin/cmgen`, `.../bin/filamesh`).

View File

@@ -0,0 +1,31 @@
plugins {
id 'groovy-gradle-plugin'
id 'com.gradle.plugin-publish' version '2.1.0'
}
group = "com.google.android.filament"
version = "0.1.0"
gradlePlugin {
website = "https://github.com/google/filament/tree/main/android/gradle-plugin"
vcsUrl = "https://github.com/google/filament/tree/main/android/gradle-plugin"
plugins {
create("filament-tools") {
id = "com.google.android.filament-tools"
displayName = "Filament Tools Gradle Plugin"
description = "A plugin that helps integrate Filament into Android projects"
tags.addAll('android', 'graphics', 'rendering', 'filament', '3d', 'gltf', 'native')
implementationClass = "com.google.android.filament.gradle.FilamentPlugin"
}
}
}
repositories {
mavenCentral()
gradlePluginPortal()
}
dependencies {
implementation "com.google.gradle:osdetector-gradle-plugin:1.7.3"
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.gradle
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
class FilamentExtension {
final ToolsLocator tools
final DirectoryProperty materialInputDir
final DirectoryProperty materialOutputDir
final Property<String> cmgenArgs
final RegularFileProperty iblInputFile
final DirectoryProperty iblOutputDir
final RegularFileProperty meshInputFile
final DirectoryProperty meshOutputDir
FilamentExtension(Project project) {
this.tools = new ToolsLocator(project)
this.materialInputDir = project.objects.directoryProperty()
this.materialOutputDir = project.objects.directoryProperty()
this.cmgenArgs = project.objects.property(String)
this.iblInputFile = project.objects.fileProperty()
this.iblOutputDir = project.objects.directoryProperty()
this.meshInputFile = project.objects.fileProperty()
this.meshOutputDir = project.objects.directoryProperty()
}
void matc(Action<ToolsLocator.ToolConfig> action) {
action.execute(tools.matc)
}
void cmgen(Action<ToolsLocator.ToolConfig> action) {
action.execute(tools.cmgen)
}
void filamesh(Action<ToolsLocator.ToolConfig> action) {
action.execute(tools.filamesh)
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.gradle
import org.gradle.api.Plugin
import org.gradle.api.Project
class FilamentPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
project.pluginManager.apply("com.google.osdetector")
FilamentExtension extension = project.extensions.create("filament", FilamentExtension, project)
project.afterEvaluate {
extension.tools.resolve(project)
project.tasks.register("filamentCompileMaterials", MaterialCompileTask) {
enabled = extension.materialInputDir.isPresent() && extension.materialOutputDir.isPresent()
inputDir.set(extension.materialInputDir.getOrNull())
outputDir.set(extension.materialOutputDir.getOrNull())
matcTool.from(extension.tools.matcToolFiles)
}
project.tasks.register("filamentGenerateIbl", IblGenerateTask) {
enabled = extension.iblInputFile.isPresent() && extension.iblOutputDir.isPresent()
cmgenArgs = extension.cmgenArgs
inputFile.set(extension.iblInputFile.getOrNull())
outputDir.set(extension.iblOutputDir.getOrNull())
cmgenTool.from(extension.tools.cmgenToolFiles)
}
project.tasks.register("filamentCompileMesh", MeshCompileTask) {
enabled = extension.meshInputFile.isPresent() && extension.meshOutputDir.isPresent()
inputFile = extension.meshInputFile.getOrNull()
outputDir = extension.meshOutputDir.getOrNull()
filameshTool.from(extension.tools.filameshToolFiles)
}
project.preBuild.dependsOn "filamentCompileMaterials"
project.preBuild.dependsOn "filamentGenerateIbl"
project.preBuild.dependsOn "filamentCompileMesh"
}
}
}

View File

@@ -0,0 +1,126 @@
/*
* Copyright (C) 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.gradle
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.file.FileType
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.process.ExecOperations
import org.gradle.work.ChangeType
import org.gradle.work.Incremental
import org.gradle.work.InputChanges
import org.gradle.api.tasks.incremental.InputFileDetails
import javax.inject.Inject
abstract class IblGenerateTask extends DefaultTask {
@Input
@Optional
abstract Property<String> getCmgenArgs()
@Incremental
@InputFile
abstract RegularFileProperty getInputFile()
@OutputDirectory
abstract DirectoryProperty getOutputDir()
@InputFiles
abstract ConfigurableFileCollection getCmgenTool()
@Inject
abstract FileSystemOperations getFileSystemOperations()
@Inject
abstract ExecOperations getExecOperations()
@Inject
abstract ObjectFactory getObjectFactory()
@TaskAction
void execute(InputChanges inputs) {
if (cmgenTool.empty) {
throw new IllegalStateException(
"cmgen executable not configured. Please configure the 'cmgen' block in the " +
"'filament' extension or set the 'com.google.android.filament.tools-dir' " +
"property."
)
}
File cmgen = getCmgenTool().singleFile
if (!cmgen.exists()) {
throw new IllegalStateException("cmgen executable does not exist: ${cmgen.absolutePath}")
}
if (!cmgen.canExecute()) {
cmgen.setExecutable(true)
}
if (!inputs.incremental) {
getFileSystemOperations().delete {
delete(getObjectFactory().fileTree().from(getOutputDir()).matching { include '*' })
}
}
inputs.getFileChanges(getInputFile()).each { InputFileDetails change ->
if (change.fileType == FileType.DIRECTORY) return
def file = change.file
if (change.changeType == ChangeType.REMOVED) {
computeOutputFile(file).delete()
} else {
println "Generating IBL: ${file.name}"
def outputPath = getOutputDir().get().asFile
def commandArgs = getCmgenArgs().getOrNull()
if (commandArgs == null) {
// Default args if not provided
commandArgs = '-q -x ' + outputPath + ' --format=rgb32f ' +
'--extract-blur=0.08 --extract=' + outputPath.absolutePath
}
def argsList = commandArgs.split(' ').toList()
argsList.add(file.absolutePath)
getExecOperations().exec { spec ->
spec.executable(cmgen)
spec.args(argsList)
}
}
}
}
File computeOutputFile(final File file) {
String name = file.name
int dotIndex = name.lastIndexOf('.')
String baseName = dotIndex > 0 ? name.substring(0, dotIndex) : name
return getOutputDir().file(baseName).get().asFile
}
}

View File

@@ -0,0 +1,147 @@
/*
* Copyright (C) 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.gradle
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.file.FileType
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.SkipWhenEmpty
import org.gradle.api.tasks.TaskAction
import org.gradle.process.ExecOperations
import org.gradle.work.ChangeType
import org.gradle.work.Incremental
import org.gradle.work.InputChanges
import javax.inject.Inject
abstract class MaterialCompileTask extends DefaultTask {
@Incremental
@InputDirectory
@PathSensitive(PathSensitivity.RELATIVE)
abstract DirectoryProperty getInputDir()
@OutputDirectory
abstract DirectoryProperty getOutputDir()
@InputFiles
@PathSensitive(PathSensitivity.NONE)
abstract ConfigurableFileCollection getMatcTool()
@Inject
abstract ExecOperations getExecOperations()
@Inject
abstract FileSystemOperations getFileSystemOperations()
@Inject
abstract ObjectFactory getObjectFactory()
@Inject
abstract ProviderFactory getProviderFactory()
@TaskAction
void compile(InputChanges inputs) {
if (matcTool.empty) {
throw new IllegalStateException(
"matc executable not configured. Please configure the 'matc' block in the " +
"'filament' extension or set the 'com.google.android.filament.tools-dir' " +
"property."
)
}
File matc = matcTool.singleFile
if (!matc.exists()) {
throw new IllegalStateException("matc executable does not exist: ${matc.absolutePath}")
}
if (!matc.canExecute()) {
matc.setExecutable(true)
}
if (!inputs.incremental) {
getFileSystemOperations().delete {
delete(getObjectFactory().fileTree().from(getOutputDir()).matching {
include '*.filamat'
})
}
}
def pf = getProviderFactory()
def excludeVulkanProperty = pf.gradleProperty("com.google.android.filament.exclude-vulkan")
def includeWebGpuProperty = pf.gradleProperty("com.google.android.filament.include-webgpu")
def matNoOptProperty = pf.gradleProperty("com.google.android.filament.matnopt")
def excludeVulkan = excludeVulkanProperty.orNull == "true"
def includeWebGpu = includeWebGpuProperty.orNull == "true"
def matNoOpt = matNoOptProperty.orNull == "true"
inputs.getFileChanges(getInputDir()).each { change ->
if (change.fileType == FileType.DIRECTORY) return
File file = change.file
File outputFile = computeOutputFile(file)
if (change.changeType == ChangeType.REMOVED) {
outputFile.delete()
} else {
println "Compiling material: ${file.name}"
def args = []
if (!excludeVulkan) {
args += ['-a', 'vulkan']
}
if (includeWebGpu) {
args += ['-a', 'webgpu', '--variant-filter=stereo']
}
if (matNoOpt) {
args += ['-g']
}
args += [
'-a', 'opengl', '-p', 'mobile',
'-o', outputFile.absolutePath,
file.absolutePath
]
getExecOperations().exec { spec ->
spec.executable(matc)
spec.args(args)
}
}
}
}
File computeOutputFile(File inputFile) {
String baseName = inputFile.name
int dotIndex = baseName.lastIndexOf('.')
if (dotIndex > 0) {
baseName = baseName.substring(0, dotIndex)
}
return getOutputDir().file("${baseName}.filamat").get().asFile
}
}

View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.gradle
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.file.FileType
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.model.ObjectFactory
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.process.ExecOperations
import org.gradle.work.ChangeType
import org.gradle.work.Incremental
import org.gradle.work.InputChanges
import javax.inject.Inject
abstract class MeshCompileTask extends DefaultTask {
@Incremental
@InputFile
@PathSensitive(PathSensitivity.RELATIVE)
abstract RegularFileProperty getInputFile()
@OutputDirectory
abstract DirectoryProperty getOutputDir()
@InputFiles
@PathSensitive(PathSensitivity.NONE)
abstract ConfigurableFileCollection getFilameshTool()
@Inject
abstract ExecOperations getExecOperations()
@Inject
abstract FileSystemOperations getFileSystemOperations()
@Inject
abstract ObjectFactory getObjectFactory()
@TaskAction
void compile(InputChanges inputs) {
if (filameshTool.empty) {
throw new IllegalStateException(
"filamesh executable not configured. Please configure the 'filamesh' block in the " +
"'filament' extension or set the 'com.google.android.filament.tools-dir' " +
"property."
)
}
File filamesh = filameshTool.singleFile
if (!filamesh.exists()) {
throw new IllegalStateException("filamesh executable does not exist: ${filamesh.absolutePath}")
}
if (!filamesh.canExecute()) {
filamesh.setExecutable(true)
}
if (!inputs.incremental) {
getFileSystemOperations().delete {
delete(getObjectFactory().fileTree().from(getOutputDir()).matching {
include '*.filamesh'
})
}
}
inputs.getFileChanges(inputFile).each { change ->
if (change.fileType == FileType.DIRECTORY) return
File file = change.file
File outputFile = computeOutputFile(file)
if (change.changeType == ChangeType.REMOVED) {
outputFile.delete()
} else {
println "Compiling mesh: ${file.name}"
getExecOperations().exec { spec ->
spec.executable(filamesh)
spec.args(file.absolutePath, outputFile.absolutePath)
}
}
}
}
File computeOutputFile(File inputFile) {
String baseName = inputFile.name
int dotIndex = baseName.lastIndexOf('.')
if (dotIndex > 0) {
baseName = baseName.substring(0, dotIndex)
}
return getOutputDir().file("${baseName}.filamesh").get().asFile
}
}

View File

@@ -0,0 +1,114 @@
/*
* Copyright (C) 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.gradle
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.file.FileCollection
import org.gradle.internal.os.OperatingSystem
import java.nio.file.Paths
class ToolsLocator {
static class ToolConfig {
String artifact
String path
FileCollection files
}
final ToolConfig matc = new ToolConfig()
final ToolConfig cmgen = new ToolConfig()
final ToolConfig filamesh = new ToolConfig()
private final Project project
ToolsLocator(Project project) {
this.project = project
}
void resolve(Project project) {
resolveTool(matc, "matc")
resolveTool(cmgen, "cmgen")
resolveTool(filamesh, "filamesh")
}
/**
* Resolves a specific tool by its name and sets the {@link ToolConfig#files} property of the
* provided {@link ToolConfig} object. It first attempts to locate the tool based on a Gradle
* property `com.google.android.filament.tools-dir` if present, otherwise it resolves the tool
* through a Gradle configuration.
*
* @param tool The {@link ToolConfig} object whose {@code files} property will be set.
* @param name The name of the tool (e.g., "matc", "cmgen").
*/
private void resolveTool(ToolConfig tool, String name) {
// Find the OS classifier, e.g. 'osx-aarch_64'.
def classifier =
project.extensions.getByType(com.google.gradle.osdetector.OsDetector).classifier
// If com.google.android.filament.tools-dir is set to a non-empty string, we'll use it as
// the tool's base path.
def toolsDirProp = project.providers.gradleProperty("com.google.android.filament.tools-dir")
if (toolsDirProp.isPresent() && !toolsDirProp.get().trim().isEmpty()) {
def toolsDir = toolsDirProp.get()
def path = OperatingSystem.current().isWindows() ?
"${toolsDir}/bin/${name}.exe" :
"${toolsDir}/bin/${name}"
tool.files = project.files(path)
return
}
// If an explicit path for the tool is provided in ToolConfig
// (e.g. matc { path = 'path/to/tool' }), use it directly.
if (tool.path) {
tool.files = project.files(tool.path)
return
}
// Otherwise, if an artifact is provided
// (e.g. matc { artifact = 'com.google.android.filament:matc:1.68.5' }), resolve it.
if (tool.artifact) {
String depString = tool.artifact
// In Gradle, a configuration is a named, manageable group of dependencies.
// Resolve the tool artifact using a detached configuration. A detached configuration
// is a temporary, isolated configuration that is not part of the project's regular
// configuration hierarchy.
Configuration config = project.configurations.detachedConfiguration()
config.setTransitive(false) // We only want the tool itself, not its dependencies
def dep = project.dependencies.create("${depString}:${classifier}@exe")
config.dependencies.add(dep)
// A Gradle Configuration implements FileCollection. When treated as a FileCollection,
// it represents the resolved files of its dependencies.
tool.files = config
}
}
FileCollection getMatcToolFiles() {
return matc.files ?: project.files()
}
FileCollection getCmgenToolFiles() {
return cmgen.files ?: project.files()
}
FileCollection getFilameshToolFiles() {
return filamesh.files ?: project.files()
}
}

View File

@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.67.1
VERSION_NAME=1.70.1
POM_DESCRIPTION=Real-time physically based rendering engine for Android.

View File

@@ -94,6 +94,13 @@ afterEvaluate { project ->
}
signing {
def signingKey = findProperty("signingKey")
def signingPassword = findProperty("signingPassword")
if (signingKey && signingPassword) {
println("Signing with in-memory keys")
useInMemoryPgpKeys(signingKey, signingPassword)
}
publishing.publications.all { publication ->
sign publication
}

View File

@@ -80,54 +80,12 @@ frame and the external texture are perfectly synchronized.
![Stream Test](../../docs/images/samples/sample_stream_test.jpg)
## Prerequisites
## Building Samples
Before you start, make sure to read [Filament's README](../../README.md). You need to be able to
compile Filament's native library and Filament's AAR for this project. The easiest way to proceed
is to install all the required dependencies and to run the following commands at the root of the
source tree:
source tree.
```shell
./build.sh -p desktop -i release
./build.sh -p android release
```
To build the samples, please follow the steps described in [BUILDING.md](../../BUILDING.md#android)
This will build all the native components and the AAR required by this sample application.
If you do not use the build script, you must set the `filament_tools_dir` property when invoking
Gradle, either from the command line or from `local.properties`. This property must point to the
distribution/install directory for desktop (produced by make/ninja install). This directory must
contain `bin/matc` and `bin/cmgen`.
Example:
```shell
./gradlew -Pfilament_tools_dir=../../dist-release assembleDebug
```
## Important: SDK location
Either ensure your `ANDROID_HOME` environment variable is set or make sure the root project
contains a `local.properties` file with the `sdk.dir` property pointing to your installation of
the Android SDK.
## Compiling
### Android Studio
You must use the latest stable release of Android Studio. To open the project, point Studio to the
`android` folder. After opening the project and syncing to gradle, select the sample of your choice
using the drop-down widget in the toolbar.
To compile and run each sample make sure you have selected the appropriate build variant
(arm7, arm8, x86 or x86_64). If you are not sure you can simply select the "universal"
variant which includes all the other ones.
### Command Line
From the `android` directory in the project root:
```shell
./gradlew :samples:sample-hello-triangle:installDebug
```
Replace `sample-hello-triangle` with your preferred project.

View File

@@ -1,7 +1,7 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'filament-tools-plugin'
id 'com.google.android.filament-tools'
}
project.ext.isSample = true
@@ -10,7 +10,7 @@ kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
filament {
cmgenArgs = "-q --format=ktx --size=256 --extract-blur=0.1 --deploy=src/main/assets/envs/default_env"
iblInputFile = project.layout.projectDirectory.file("../../../third_party/environments/lightroom_14b.hdr")
iblOutputDir = project.layout.projectDirectory.dir("src/main/assets/envs")

View File

@@ -389,9 +389,9 @@ class MainActivity : Activity() {
viewerContent.assetLights = modelViewer.asset?.lightEntities
automation.applySettings(modelViewer.engine, json, viewerContent)
modelViewer.view.colorGrading = automation.getColorGrading(modelViewer.engine)
modelViewer.cameraFocalLength = automation.viewerOptions.cameraFocalLength
modelViewer.cameraNear = automation.viewerOptions.cameraNear
modelViewer.cameraFar = automation.viewerOptions.cameraFar
modelViewer.cameraFocalLength = automation.cameraSettings.focalLength
modelViewer.cameraNear = automation.cameraSettings.near
modelViewer.cameraFar = automation.cameraSettings.far
updateRootTransform()
}

View File

@@ -1,7 +1,7 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'filament-tools-plugin'
id 'com.google.android.filament-tools'
}
project.ext.isSample = true
@@ -10,7 +10,7 @@ kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
filament {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
}

View File

@@ -1,7 +1,7 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'filament-tools-plugin'
id 'com.google.android.filament-tools'
}
project.ext.isSample = true
@@ -10,7 +10,7 @@ kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
filament {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
}

View File

@@ -1,7 +1,7 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'filament-tools-plugin'
id 'com.google.android.filament-tools'
}
project.ext.isSample = true
@@ -10,7 +10,7 @@ kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
filament {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")

View File

@@ -1,7 +1,7 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'filament-tools-plugin'
id 'com.google.android.filament-tools'
}
project.ext.isSample = true
@@ -10,7 +10,7 @@ kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
filament {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
}

View File

@@ -1,7 +1,7 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'filament-tools-plugin'
id 'com.google.android.filament-tools'
}
project.ext.isSample = true
@@ -10,7 +10,7 @@ kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
filament {
meshInputFile = project.layout.projectDirectory.file("../../../third_party/models/shader_ball/shader_ball.obj")
meshOutputDir = project.layout.projectDirectory.dir("src/main/assets/models")

View File

@@ -1,7 +1,7 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'filament-tools-plugin'
id 'com.google.android.filament-tools'
}
project.ext.isSample = true
@@ -10,7 +10,7 @@ kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
filament {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
}

View File

@@ -1,7 +1,7 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'filament-tools-plugin'
id 'com.google.android.filament-tools'
}
project.ext.isSample = true
@@ -10,7 +10,7 @@ kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
filament {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
}

View File

@@ -1,7 +1,7 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'filament-tools-plugin'
id 'com.google.android.filament-tools'
}
project.ext.isSample = true
@@ -10,7 +10,7 @@ kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
filament {
iblInputFile = project.layout.projectDirectory.file("../../../third_party/environments/studio_small_02_2k.hdr")
iblOutputDir = project.layout.projectDirectory.dir("src/main/assets/envs")
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")

View File

@@ -0,0 +1,57 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'com.google.android.filament-tools'
}
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filament {
cmgenArgs = "-q --format=ktx --size=256 --extract-blur=0.1 --deploy=src/main/assets/envs/default_env"
iblInputFile = project.layout.projectDirectory.file("../../../third_party/environments/lightroom_14b.hdr")
iblOutputDir = project.layout.projectDirectory.dir("src/main/assets/envs")
}
// don't forget to update MainACtivity.kt when/if changing this.
tasks.register('copyDamagedHelmetGltf', Copy) {
from file("../../../third_party/models/DamagedHelmet/DamagedHelmet.glb")
into file("src/main/assets/models")
rename {String fileName -> "helmet.glb"}
}
preBuild.dependsOn copyDamagedHelmetGltf
clean.doFirst {
delete "src/main/assets/envs"
delete "src/main/assets/models"
}
android {
namespace 'com.google.android.filament.validation'
compileSdkVersion versions.compileSdk
defaultConfig {
applicationId "com.google.android.filament.validation"
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
implementation deps.kotlin
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.google.android.material:material:1.10.0'
implementation deps.coroutines.core
implementation project(':filament-android')
implementation project(':gltfio-android')
implementation project(':filament-utils-android')
}

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:label="Filament Validation"
android:supportsRtl="true"
android:largeHeap="true"
android:requestLegacyExternalStorage="true"
android:theme="@style/Theme.Material3.DayNight.NoActionBar">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
android:screenOrientation="fullSensor">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,899 @@
{
"name": "Default Test",
"backends": [
"opengl"
],
"models": {
"DamagedHelmet": "helmet.glb"
},
"presets": [
{
"name": "base",
"models": [
"DamagedHelmet"
],
"rendering": {
"camera": {
"enabled": true,
"horizontalFov": 45.0,
"center": [
0,
0,
0
],
"lookAt": [
0,
0,
-1
]
},
"view": {
"postProcessingEnabled": true,
"dithering": "NONE"
},
"tolerance": {
"maxAbsDiff": 0.1,
"maxFailingPixelsFraction": 0.0
}
}
},
{
"name": "tilted",
"rendering": {
"camera": {
"enabled": true,
"horizontalFov": 45.0,
"center": [
-4,
-2,
-3
],
"lookAt": [
0,
0,
-4
]
}
}
}
],
"tests": [
{
"name": "basic",
"apply_presets": [
"base"
]
},
{
"name": "rotated",
"apply_presets": [
"base",
"tilted"
]
},
{
"name": "ssao",
"apply_presets": [
"base"
],
"rendering": {
"view.ssao.enabled": true
}
},
{
"name": "msaa",
"apply_presets": [
"base"
],
"rendering": {
"view.msaa.enabled": true
}
},
{
"name": "bloom",
"apply_presets": [
"base",
"tilted"
],
"rendering": {
"view.bloom.enabled": true
}
},
{
"name": "aa_none",
"apply_presets": [
"base"
],
"rendering": {
"view.antiAliasing": "NONE"
}
},
{
"name": "aa_fxaa",
"apply_presets": [
"base"
],
"rendering": {
"view.antiAliasing": "FXAA"
}
},
{
"name": "dithering_none",
"apply_presets": [
"base"
],
"rendering": {
"view.dithering": "NONE"
}
},
{
"name": "msaa_8",
"apply_presets": [
"base"
],
"rendering": {
"view.msaa.enabled": true,
"view.msaa.sampleCount": 8
}
},
{
"name": "taa_custom",
"apply_presets": [
"base"
],
"rendering": {
"view.taa.enabled": true,
"view.taa.feedback": 0.2,
"view.taa.jitterPattern": "HALTON_23_X16"
}
},
{
"name": "ssao_gtao",
"apply_presets": [
"base"
],
"rendering": {
"view.ssao.enabled": true,
"view.ssao.aoType": "GTAO"
}
},
{
"name": "ssao_sao",
"apply_presets": [
"base"
],
"rendering": {
"view.ssao.enabled": true,
"view.ssao.aoType": "SAO"
}
},
{
"name": "ssao_radius_high",
"apply_presets": [
"base"
],
"rendering": {
"view.ssao.enabled": true,
"view.ssao.radius": 1.0
}
},
{
"name": "ssao_radius_low",
"apply_presets": [
"base"
],
"rendering": {
"view.ssao.enabled": true,
"view.ssao.radius": 0.1
}
},
{
"name": "ssao_power_high",
"apply_presets": [
"base"
],
"rendering": {
"view.ssao.enabled": true,
"view.ssao.power": 2.0
}
},
{
"name": "ssao_power_low",
"apply_presets": [
"base"
],
"rendering": {
"view.ssao.enabled": true,
"view.ssao.power": 0.5
}
},
{
"name": "ssao_bias_high",
"apply_presets": [
"base"
],
"rendering": {
"view.ssao.enabled": true,
"view.ssao.bias": 0.05
}
},
{
"name": "ssao_resolution_half",
"apply_presets": [
"base"
],
"rendering": {
"view.ssao.enabled": true,
"view.ssao.resolution": 0.5
}
},
{
"name": "ssao_resolution_full",
"apply_presets": [
"base"
],
"rendering": {
"view.ssao.enabled": true,
"view.ssao.resolution": 1.0
}
},
{
"name": "ssao_intensity_high",
"apply_presets": [
"base"
],
"rendering": {
"view.ssao.enabled": true,
"view.ssao.intensity": 2.0
}
},
{
"name": "ssao_bent_normals",
"apply_presets": [
"base"
],
"rendering": {
"view.ssao.enabled": true,
"view.ssao.bentNormals": true
}
},
{
"name": "ssao_quality_ultra",
"apply_presets": [
"base"
],
"rendering": {
"view.ssao.enabled": true,
"view.ssao.quality": "ULTRA"
}
},
{
"name": "ssao_quality_low",
"apply_presets": [
"base"
],
"rendering": {
"view.ssao.enabled": true,
"view.ssao.quality": "LOW"
}
},
{
"name": "ssao_lowPassFilter_ultra",
"apply_presets": [
"base"
],
"rendering": {
"view.ssao.enabled": true,
"view.ssao.lowPassFilter": "ULTRA"
}
},
{
"name": "ssao_upsampling_ultra",
"apply_presets": [
"base"
],
"rendering": {
"view.ssao.enabled": true,
"view.ssao.upsampling": "ULTRA"
}
},
{
"name": "ssr_basic",
"apply_presets": [
"base"
],
"rendering": {
"view.screenSpaceReflections.enabled": true
}
},
{
"name": "ssr_thickness_high",
"apply_presets": [
"base"
],
"rendering": {
"view.screenSpaceReflections.enabled": true,
"view.screenSpaceReflections.thickness": 0.5
}
},
{
"name": "ssr_bias_high",
"apply_presets": [
"base"
],
"rendering": {
"view.screenSpaceReflections.enabled": true,
"view.screenSpaceReflections.bias": 0.1
}
},
{
"name": "ssr_maxDistance_high",
"apply_presets": [
"base"
],
"rendering": {
"view.screenSpaceReflections.enabled": true,
"view.screenSpaceReflections.maxDistance": 5.0
}
},
{
"name": "ssr_stride_high",
"apply_presets": [
"base"
],
"rendering": {
"view.screenSpaceReflections.enabled": true,
"view.screenSpaceReflections.stride": 4.0
}
},
{
"name": "ssr_stride_low",
"apply_presets": [
"base"
],
"rendering": {
"view.screenSpaceReflections.enabled": true,
"view.screenSpaceReflections.stride": 1.0
}
},
{
"name": "ssr_thickness_low",
"apply_presets": [
"base"
],
"rendering": {
"view.screenSpaceReflections.enabled": true,
"view.screenSpaceReflections.thickness": 0.01
}
},
{
"name": "ssr_maxDistance_low",
"apply_presets": [
"base"
],
"rendering": {
"view.screenSpaceReflections.enabled": true,
"view.screenSpaceReflections.maxDistance": 1.0
}
},
{
"name": "ssr_bias_low",
"apply_presets": [
"base"
],
"rendering": {
"view.screenSpaceReflections.enabled": true,
"view.screenSpaceReflections.bias": 0.001
}
},
{
"name": "ssr_quality_combo",
"apply_presets": [
"base"
],
"rendering": {
"view.screenSpaceReflections.enabled": true,
"view.screenSpaceReflections.thickness": 0.2,
"view.screenSpaceReflections.stride": 2.0
}
},
{
"name": "bloom_levels_high",
"apply_presets": [
"base"
],
"rendering": {
"view.bloom.enabled": true,
"view.bloom.levels": 8
}
},
{
"name": "bloom_levels_low",
"apply_presets": [
"base"
],
"rendering": {
"view.bloom.enabled": true,
"view.bloom.levels": 4
}
},
{
"name": "bloom_resolution_high",
"apply_presets": [
"base"
],
"rendering": {
"view.bloom.enabled": true,
"view.bloom.resolution": 1024
}
},
{
"name": "bloom_strength_high",
"apply_presets": [
"base"
],
"rendering": {
"view.bloom.enabled": true,
"view.bloom.strength": 0.5
}
},
{
"name": "bloom_strength_low",
"apply_presets": [
"base"
],
"rendering": {
"view.bloom.enabled": true,
"view.bloom.strength": 0.01
}
},
{
"name": "bloom_blendMode_interpolate",
"apply_presets": [
"base"
],
"rendering": {
"view.bloom.enabled": true,
"view.bloom.blendMode": "INTERPOLATE"
}
},
{
"name": "bloom_no_threshold",
"apply_presets": [
"base"
],
"rendering": {
"view.bloom.enabled": true,
"view.bloom.threshold": false
}
},
{
"name": "bloom_quality_high",
"apply_presets": [
"base"
],
"rendering": {
"view.bloom.enabled": true,
"view.bloom.quality": "HIGH"
}
},
{
"name": "bloom_lensflare",
"apply_presets": [
"base"
],
"rendering": {
"view.bloom.enabled": true,
"view.bloom.lensFlare": true
}
},
{
"name": "bloom_lensflare_no_starburst",
"apply_presets": [
"base"
],
"rendering": {
"view.bloom.enabled": true,
"view.bloom.lensFlare": true,
"view.bloom.starburst": false
}
},
{
"name": "bloom_lensflare_chromatic",
"apply_presets": [
"base"
],
"rendering": {
"view.bloom.enabled": true,
"view.bloom.lensFlare": true,
"view.bloom.chromaticAberration": 0.05
}
},
{
"name": "bloom_lensflare_ghosts",
"apply_presets": [
"base"
],
"rendering": {
"view.bloom.enabled": true,
"view.bloom.lensFlare": true,
"view.bloom.ghostCount": 8
}
},
{
"name": "bloom_lensflare_ghostSpacing",
"apply_presets": [
"base"
],
"rendering": {
"view.bloom.enabled": true,
"view.bloom.lensFlare": true,
"view.bloom.ghostSpacing": 0.8
}
},
{
"name": "bloom_halo_thick",
"apply_presets": [
"base"
],
"rendering": {
"view.bloom.enabled": true,
"view.bloom.lensFlare": true,
"view.bloom.haloThickness": 0.2
}
},
{
"name": "bloom_halo_radius",
"apply_presets": [
"base"
],
"rendering": {
"view.bloom.enabled": true,
"view.bloom.lensFlare": true,
"view.bloom.haloRadius": 0.5
}
},
{
"name": "dof_basic",
"apply_presets": [
"base"
],
"rendering": {
"view.dof.enabled": true
}
},
{
"name": "dof_cocScale_high",
"apply_presets": [
"base"
],
"rendering": {
"view.dof.enabled": true,
"view.dof.cocScale": 2.0
}
},
{
"name": "dof_cocScale_low",
"apply_presets": [
"base"
],
"rendering": {
"view.dof.enabled": true,
"view.dof.cocScale": 0.5
}
},
{
"name": "dof_cocAspectRatio",
"apply_presets": [
"base"
],
"rendering": {
"view.dof.enabled": true,
"view.dof.cocAspectRatio": 2.0
}
},
{
"name": "dof_maxApertureDiameter",
"apply_presets": [
"base"
],
"rendering": {
"view.dof.enabled": true,
"view.dof.maxApertureDiameter": 0.05
}
},
{
"name": "dof_filter_none",
"apply_presets": [
"base"
],
"rendering": {
"view.dof.enabled": true,
"view.dof.filter": "NONE"
}
},
{
"name": "dof_nativeResolution",
"apply_presets": [
"base"
],
"rendering": {
"view.dof.enabled": true,
"view.dof.nativeResolution": true
}
},
{
"name": "dof_rings_high",
"apply_presets": [
"base"
],
"rendering": {
"view.dof.enabled": true,
"view.dof.foregroundRingCount": 5,
"view.dof.backgroundRingCount": 5
}
},
{
"name": "dof_rings_low",
"apply_presets": [
"base"
],
"rendering": {
"view.dof.enabled": true,
"view.dof.foregroundRingCount": 3,
"view.dof.backgroundRingCount": 3
}
},
{
"name": "dof_max_coc",
"apply_presets": [
"base"
],
"rendering": {
"view.dof.enabled": true,
"view.dof.maxForegroundCOC": 16,
"view.dof.maxBackgroundCOC": 16
}
},
{
"name": "fog_basic",
"apply_presets": [
"base"
],
"rendering": {
"view.fog.enabled": true
}
},
{
"name": "fog_distance",
"apply_presets": [
"base"
],
"rendering": {
"view.fog.enabled": true,
"view.fog.distance": 10.0
}
},
{
"name": "fog_cutOffDistance",
"apply_presets": [
"base"
],
"rendering": {
"view.fog.enabled": true,
"view.fog.cutOffDistance": 100.0
}
},
{
"name": "fog_maximumOpacity",
"apply_presets": [
"base"
],
"rendering": {
"view.fog.enabled": true,
"view.fog.maximumOpacity": 0.5
}
},
{
"name": "fog_height",
"apply_presets": [
"base"
],
"rendering": {
"view.fog.enabled": true,
"view.fog.height": 5.0
}
},
{
"name": "fog_heightFalloff",
"apply_presets": [
"base"
],
"rendering": {
"view.fog.enabled": true,
"view.fog.heightFalloff": 0.5
}
},
{
"name": "fog_density_high",
"apply_presets": [
"base"
],
"rendering": {
"view.fog.enabled": true,
"view.fog.density": 0.5
}
},
{
"name": "fog_inScatteringStart",
"apply_presets": [
"base"
],
"rendering": {
"view.fog.enabled": true,
"view.fog.inScatteringStart": 5.0
}
},
{
"name": "fog_inScatteringSize",
"apply_presets": [
"base"
],
"rendering": {
"view.fog.enabled": true,
"view.fog.inScatteringSize": 10.0
}
},
{
"name": "fog_fogColorFromIbl",
"apply_presets": [
"base"
],
"rendering": {
"view.fog.enabled": true,
"view.fog.fogColorFromIbl": true
}
},
{
"name": "vignette_basic",
"apply_presets": [
"base"
],
"rendering": {
"view.vignette.enabled": true
}
},
{
"name": "vignette_midPoint",
"apply_presets": [
"base"
],
"rendering": {
"view.vignette.enabled": true,
"view.vignette.midPoint": 0.8
}
},
{
"name": "vignette_roundness_circle",
"apply_presets": [
"base"
],
"rendering": {
"view.vignette.enabled": true,
"view.vignette.roundness": 1.0
}
},
{
"name": "vignette_roundness_rect",
"apply_presets": [
"base"
],
"rendering": {
"view.vignette.enabled": true,
"view.vignette.roundness": 0.0
}
},
{
"name": "vignette_feather_sharp",
"apply_presets": [
"base"
],
"rendering": {
"view.vignette.enabled": true,
"view.vignette.feather": 0.1
}
},
{
"name": "cg_filmic",
"apply_presets": [
"base"
],
"rendering": {
"view.colorGrading.toneMapping": "FILMIC"
}
},
{
"name": "cg_aces",
"apply_presets": [
"base"
],
"rendering": {
"view.colorGrading.toneMapping": "ACES"
}
},
{
"name": "cg_agx",
"apply_presets": [
"base"
],
"rendering": {
"view.colorGrading.toneMapping": "AGX"
}
},
{
"name": "cg_pbr_neutral",
"apply_presets": [
"base"
],
"rendering": {
"view.colorGrading.toneMapping": "PBR_NEUTRAL"
}
},
{
"name": "cg_contrast_high",
"apply_presets": [
"base"
],
"rendering": {
"view.colorGrading.contrast": 1.5
}
},
{
"name": "cg_saturation_high",
"apply_presets": [
"base"
],
"rendering": {
"view.colorGrading.saturation": 1.5
}
},
{
"name": "cg_exposure_high",
"apply_presets": [
"base"
],
"rendering": {
"view.colorGrading.exposure": 1.0
}
},
{
"name": "shadow_vsm",
"apply_presets": [
"base"
],
"rendering": {
"view.shadowType": "VSM"
}
},
{
"name": "shadow_vsm_anisotropy",
"apply_presets": [
"base"
],
"rendering": {
"view.shadowType": "VSM",
"view.vsmShadowOptions.anisotropy": 2
}
},
{
"name": "shadow_vsm_highPrecision",
"apply_presets": [
"base"
],
"rendering": {
"view.shadowType": "VSM",
"view.vsmShadowOptions.highPrecision": true
}
}
]
}

View File

@@ -0,0 +1,529 @@
/*
* Copyright (C) 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.validation
import android.app.Activity
import android.app.AlertDialog
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Color
import android.os.Bundle
import android.text.Html
import android.util.Log
import android.view.Choreographer
import android.view.SurfaceView
import android.view.View
import android.view.WindowManager
import android.widget.ArrayAdapter
import android.widget.Button
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.Spinner
import android.widget.TextView
import com.google.android.filament.utils.KTX1Loader
import com.google.android.filament.utils.ModelViewer
import com.google.android.filament.utils.Utils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.nio.ByteBuffer
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
class MainActivity : Activity(), ValidationRunner.Callback {
companion object {
init {
Utils.init()
System.loadLibrary("filament-utils-jni")
}
private const val TAG = "FilamentValidation"
}
private lateinit var surfaceView: SurfaceView
private lateinit var choreographer: Choreographer
private lateinit var modelViewer: ModelViewer
private lateinit var statusTextView: TextView
private lateinit var testResultsHeader: TextView
private lateinit var resultsContainer: LinearLayout
private lateinit var inputManager: ValidationInputManager
private var currentInput: ValidationInputManager.ValidationInput? = null
// UI Elements
private lateinit var runButton: Button
private lateinit var loadButton: Button
private lateinit var optionsButton: Button
private var resultManager: ValidationResultManager? = null
private var validationRunner: ValidationRunner? = null
// Frame callback
private val frameScheduler = object : Choreographer.FrameCallback {
override fun doFrame(frameTimeNanos: Long) {
choreographer.postFrameCallback(this)
modelViewer.render(frameTimeNanos)
validationRunner?.onFrame(frameTimeNanos)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// SurfaceView container
surfaceView = findViewById(R.id.surface_view)
surfaceView.holder.setFixedSize(512, 512)
statusTextView = findViewById(R.id.status_text)
testResultsHeader = findViewById(R.id.test_results_header)
resultsContainer = findViewById(R.id.results_container)
runButton = findViewById(R.id.run_button)
loadButton = findViewById(R.id.load_button)
optionsButton = findViewById(R.id.options_button)
// Setup Run Button
runButton.setOnClickListener {
currentInput?.let { input ->
// Always use the generateGoldens flag from the intent/input
startValidation(input)
}
}
// Setup Load Button
loadButton.setOnClickListener {
showLoadDialog()
}
// Setup Options Menu Button
optionsButton.setOnClickListener { view ->
val popup = android.widget.PopupMenu(this, view)
popup.menu.add(0, 1, 0, "Generate Golden")
popup.menu.add(0, 2, 0, "Export Test")
popup.menu.add(0, 3, 0, "Export Result")
popup.menu.add(0, 4, 0, "Test ADB Info")
popup.menu.add(0, 5, 0, "Result ADB Info")
popup.setOnMenuItemClickListener { item ->
when (item.itemId) {
1 -> {
currentInput?.let { input ->
val goldenInput = input.copy(generateGoldens = true)
startValidation(goldenInput)
}
}
2 -> exportTestBundleAction()
3 -> exportTestResultsAction()
4 -> showTestAdbInfo()
5 -> showResultAdbInfo()
}
true
}
popup.show()
}
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
choreographer = Choreographer.getInstance()
modelViewer = ModelViewer(surfaceView)
inputManager = ValidationInputManager(this)
// Initialize IBL
createIndirectLight()
handleIntent()
}
private fun showLoadDialog() {
val exportDir = getExternalFilesDir(null) ?: filesDir
// Filter out result zips (starting with "results_") to only show test bundles
val zips = exportDir.listFiles { _, name ->
name.endsWith(".zip") && !name.startsWith("results_")
}?.sortedByDescending { it.lastModified() } ?: emptyList()
if (zips.isEmpty()) {
AlertDialog.Builder(this)
.setTitle("Load Test")
.setMessage("No test bundles found.")
.setPositiveButton("OK", null)
.show()
return
}
val builder = AlertDialog.Builder(this)
builder.setTitle("Select Test Bundle")
val items = zips.map { it.name }.toTypedArray()
builder.setItems(items) { dialog, which ->
val selectedFile = zips[which]
loadZipBundle(selectedFile)
dialog.dismiss()
}
builder.setNegativeButton("Cancel", null)
builder.show()
}
private fun showTestAdbInfo() {
val exportDir = getExternalFilesDir(null) ?: filesDir
val path = exportDir.absolutePath
val isInternal = path.startsWith(filesDir.absolutePath)
val message = StringBuilder()
message.append("Storage Path: $path<br><br>")
message.append("<b>--- PULL FROM DEVICE ---</b><br>")
if (isInternal) {
message.append("<tt>adb shell \"run-as $packageName cat files/&lt;filename&gt;\" &gt; &lt;filename&gt;</tt><br><br>")
} else {
message.append("<tt>adb pull $path/&lt;filename&gt; .</tt><br><br>")
}
message.append("<b>--- PUSH TO DEVICE ---</b><br>")
if (isInternal) {
message.append("1. <tt>adb push &lt;filename&gt; /sdcard/Download/</tt><br>")
message.append("2. <tt>adb shell \"run-as $packageName cp /sdcard/Download/&lt;filename&gt; files/\"</tt><br>")
} else {
message.append("<tt>adb push &lt;filename&gt; $path/</tt><br>")
}
message.append("<br>Note: Use underscores instead of spaces in &lt;filename&gt;.")
AlertDialog.Builder(this)
.setTitle("Test Bundle ADB Info")
.setMessage(Html.fromHtml(message.toString(), Html.FROM_HTML_MODE_LEGACY))
.setPositiveButton("OK", null)
.show()
}
private fun showResultAdbInfo() {
val exportDir = getExternalFilesDir(null) ?: filesDir
val path = exportDir.absolutePath
val isInternal = path.startsWith(filesDir.absolutePath)
val message = StringBuilder()
message.append("<b>--- PULL RESULTS ---</b><br>")
if (isInternal) {
message.append("<tt>adb shell \"run-as $packageName cat files/&lt;filename&gt;\" &gt; &lt;filename&gt;</tt><br><br>")
} else {
message.append("<tt>adb pull $path/&lt;filename&gt; .</tt><br><br>")
}
message.append("<b>--- AVAILABLE RESULTS ---</b><br>")
val zips = exportDir.listFiles { _, name ->
name.endsWith(".zip") && name.startsWith("results_")
}?.sortedByDescending { it.lastModified() } ?: emptyList()
if (zips.isEmpty()) {
message.append("No result zips found.<br>")
} else {
zips.forEach { file ->
message.append("${file.name}<br>")
}
}
AlertDialog.Builder(this)
.setTitle("Result ADB Info")
.setMessage(Html.fromHtml(message.toString(), Html.FROM_HTML_MODE_LEGACY))
.setPositiveButton("OK", null)
.show()
}
private fun loadZipBundle(file: File) {
statusTextView.text = "Loading ${file.name}..."
CoroutineScope(Dispatchers.Main).launch {
try {
val config = inputManager.loadFromZip(file)
val baseDir = getExternalFilesDir(null) ?: filesDir
val outputDir = File(baseDir, "validation_results").apply { mkdirs() }
// Clear existing results UI and state
resultsContainer.removeAllViews()
resultManager = null
val newInput = ValidationInputManager.ValidationInput(
config = config,
outputDir = outputDir,
generateGoldens = false,
autoRun = false,
autoExport = false,
autoExportResults = false,
sourceZip = file
)
currentInput = newInput
statusTextView.text = "Loaded ${config.name}"
Log.i(TAG, "Setting header to: Test Results: ${config.name}")
testResultsHeader.text = "${config.name}"
} catch (e: Exception) {
Log.e(TAG, "Failed to load zip", e)
statusTextView.text = "Error: ${e.message}"
}
}
}
private fun createIndirectLight() {
try {
val engine = modelViewer.engine
val scene = modelViewer.scene
val iblName = "default_env"
fun readAsset(path: String): ByteBuffer {
val input = assets.open(path)
val bytes = input.readBytes()
return ByteBuffer.wrap(bytes)
}
readAsset("envs/$iblName/${iblName}_ibl.ktx").let {
val bundle = KTX1Loader.createIndirectLight(engine, it)
scene.indirectLight = bundle.indirectLight
modelViewer.indirectLightCubemap = bundle.cubemap
scene.indirectLight!!.intensity = 30_000.0f
}
readAsset("envs/$iblName/${iblName}_skybox.ktx").let {
val bundle = KTX1Loader.createSkybox(engine, it)
scene.skybox = bundle.skybox
modelViewer.skyboxCubemap = bundle.cubemap
}
Log.i(TAG, "IBL loaded successfully")
} catch (e: Exception) {
Log.e(TAG, "Failed to load IBL", e)
statusTextView.text = "Warning: Failed to load IBL"
}
}
private fun handleIntent() {
statusTextView.text = "Resolving configuration..."
CoroutineScope(Dispatchers.Main).launch {
try {
val input = inputManager.resolveConfig(intent)
// Update header
Log.i(TAG, "handleIntent: Setting header to: Test Results: ${input.config.name}")
testResultsHeader.text = "${input.config.name}"
currentInput = input
if (input.autoRun) {
startValidation(input)
} else {
// Just show status
statusTextView.text = "Ready: ${input.config.name}"
}
} catch (e: Exception) {
Log.e(TAG, "Failed to resolve config", e)
statusTextView.text = "Error: ${e.message}"
}
}
}
private fun startValidation(input: ValidationInputManager.ValidationInput) {
try {
resultsContainer.removeAllViews()
Log.i(TAG, "Starting validation with config: ${input.config.name}")
Log.i(TAG, "Output dir: ${input.outputDir.absolutePath}")
testResultsHeader.text = "${input.config.name}"
resultManager = ValidationResultManager(input.outputDir)
validationRunner = ValidationRunner(this, modelViewer, input.config, resultManager!!)
validationRunner?.callback = this
validationRunner?.generateGoldens = input.generateGoldens
validationRunner?.start()
} catch (e: Exception) {
Log.e(TAG, "Failed to start validation", e)
statusTextView.text = "Error: ${e.message}"
}
}
override fun onResume() {
super.onResume()
choreographer.postFrameCallback(frameScheduler)
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
handleIntent()
}
override fun onPause() {
super.onPause()
choreographer.removeFrameCallback(frameScheduler)
}
override fun onDestroy() {
super.onDestroy()
choreographer.removeFrameCallback(frameScheduler)
}
private var currentRenderedBitmap: Bitmap? = null
private var currentGoldenBitmap: Bitmap? = null
private var currentDiffBitmap: Bitmap? = null
override fun onTestFinished(result: ValidationResult) {
runOnUiThread {
val status = "Test ${result.testName} finished: ${if(result.passed) "PASS" else "FAIL"}"
statusTextView.text = status
Log.i(TAG, status)
// Container for this result
val resultContainer = LinearLayout(this)
resultContainer.orientation = LinearLayout.VERTICAL
resultContainer.setPadding(0, 10, 0, 20)
// Header Layout
val headerRow = LinearLayout(this)
headerRow.orientation = LinearLayout.HORIZONTAL
headerRow.gravity = android.view.Gravity.CENTER_VERTICAL
// Status Icon + Name
val statusView = TextView(this)
val icon = if (result.passed) "" else ""
statusView.text = "$icon ${result.testName}"
statusView.setTextColor(
if (result.passed) Color.parseColor("#4CAF50") else Color.parseColor("#F44336")
)
statusView.textSize = 12f
statusView.setTypeface(null, android.graphics.Typeface.BOLD)
headerRow.addView(statusView)
// Diff Metric (only show if it's relevant/there's a diff or we just always show it like before)
val diffView = TextView(this)
diffView.text = " (Diff: ${result.diffMetric})"
diffView.textSize = 12f
diffView.setTextColor(Color.GRAY)
headerRow.addView(diffView)
resultContainer.addView(headerRow)
// Images Row
val imagesRow = LinearLayout(this)
imagesRow.orientation = LinearLayout.HORIZONTAL
fun addImage(label: String, bitmap: Bitmap?) {
if (bitmap != null) {
val container = LinearLayout(this)
container.orientation = LinearLayout.VERTICAL
container.setPadding(0, 0, 10, 0)
val labelView = TextView(this)
labelView.text = label
labelView.textSize = 9f
container.addView(labelView)
val iv = ImageView(this)
iv.setImageBitmap(bitmap) // Use the same bitmap (or copy if needed, but same is usually fine for UI)
iv.layoutParams = LinearLayout.LayoutParams(250, 250) // Smaller thumbnails
iv.scaleType = ImageView.ScaleType.FIT_CENTER
iv.setBackgroundColor(0xFF404040.toInt())
container.addView(iv)
imagesRow.addView(container)
}
}
addImage("Rendered", currentRenderedBitmap)
addImage("Golden", currentGoldenBitmap)
if (!result.passed) {
addImage("Diff", currentDiffBitmap)
}
resultContainer.addView(imagesRow)
resultsContainer.addView(resultContainer)
// Clear current images for next test
currentRenderedBitmap = null
currentGoldenBitmap = null
currentDiffBitmap = null
}
}
override fun onAllTestsFinished() {
runOnUiThread {
statusTextView.text = "All tests finished!"
Log.i(TAG, "All tests finished " + if (currentInput?.autoExport == true) "Exporting bundle" else "x")
if (currentInput?.autoExport == true) {
exportTestBundleAction()
}
if (currentInput?.autoExportResults == true) {
exportTestResultsAction()
}
}
}
private fun exportTestBundleAction() {
currentInput?.let { input ->
val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(Date())
val rm = resultManager ?: ValidationResultManager(input.outputDir)
val zip = rm.exportTestBundle(input.config, timestamp)
if (zip != null) {
val msg = "Exported Bundle: ${zip.name}"
statusTextView.text = msg
Log.i(TAG, "Exported test bundle to ${zip.absolutePath}")
} else {
statusTextView.text = "Export Bundle failed"
Log.e(TAG, "Export Bundle failed")
}
}
}
private fun exportTestResultsAction() {
currentInput?.let { input ->
val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(Date())
val rm = resultManager ?: ValidationResultManager(input.outputDir)
val zip = rm.exportTestResults(input.sourceZip, timestamp)
if (zip != null) {
val msg = "Exported Results: ${zip.name}"
statusTextView.text = msg
Log.i(TAG, "Exported results to ${zip.absolutePath}")
} else {
statusTextView.text = "Export Results failed"
Log.e(TAG, "Export Results failed")
}
}
}
override fun onStatusChanged(status: String) {
runOnUiThread {
statusTextView.text = status
}
}
override fun onImageResult(type: String, bitmap: Bitmap) {
runOnUiThread {
// Update the "live" views
when (type) {
"Rendered" -> {
currentRenderedBitmap = bitmap
}
"Golden" -> {
currentGoldenBitmap = bitmap
}
"Diff" -> {
currentDiffBitmap = bitmap
}
}
}
}
}

View File

@@ -0,0 +1,186 @@
/*
* Copyright (C) 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.validation
import org.json.JSONArray
import org.json.JSONObject
import java.io.File
import java.io.IOException
data class RenderTestConfig(
val name: String,
val backends: List<String>,
val models: Map<String, String>, // name -> path
val tests: List<TestConfig>
)
data class TestConfig(
val name: String,
val description: String?,
val backends: List<String>,
val models: Set<String>,
val rendering: JSONObject,
val tolerance: JSONObject?
)
// See test/renderdiff/FORMAT.md for the full specification matched by this parser.
class ConfigParser {
companion object {
fun parseFromPath(path: String): RenderTestConfig {
val file = File(path)
val jsonTxt = removeComments(file.readText())
val json = JSONObject(jsonTxt)
return parseRenderTestConfig(json, file.parentFile)
}
private fun removeComments(json: String): String {
return json.lines().joinToString("\n") { it.substringBefore("//") }
}
private fun parseRenderTestConfig(json: JSONObject, baseDir: File?): RenderTestConfig {
val name = json.getString("name")
val backends = json.getJSONArray("backends").toList<String>()
val modelSearchPaths = json.optJSONArray("model_search_paths")?.toList<String>() ?: emptyList()
val models = mutableMapOf<String, String>()
baseDir?.let { dir ->
modelSearchPaths.forEach { searchPath ->
val searchDir = File(dir, searchPath)
if (searchDir.exists()) {
searchDir.walkTopDown().filter { it.isFile && (it.extension == "glb" || it.extension == "gltf") }.forEach { file ->
models[file.nameWithoutExtension] = file.absolutePath
}
}
}
}
// Explicit models map override
val modelsJson = json.optJSONObject("models")
if (modelsJson != null) {
val keys = modelsJson.keys()
while (keys.hasNext()) {
val name = keys.next()
val path = modelsJson.getString(name)
// Resolve path relative to baseDir if not absolute
val file = File(path)
if (file.isAbsolute) {
models[name] = path
} else if (baseDir != null) {
models[name] = File(baseDir, path).absolutePath
} else {
models[name] = path
}
}
}
val presetsJson = json.optJSONArray("presets")
val presets = mutableMapOf<String, PresetConfig>()
if (presetsJson != null) {
for (i in 0 until presetsJson.length()) {
val p = parsePreset(presetsJson.getJSONObject(i), models.keys)
presets[p.name] = p
}
}
val testsJson = json.getJSONArray("tests")
val tests = mutableListOf<TestConfig>()
for (i in 0 until testsJson.length()) {
tests.add(parseTestConfig(testsJson.getJSONObject(i), models.keys, presets, backends))
}
return RenderTestConfig(name, backends, models, tests)
}
private fun parsePreset(json: JSONObject, existingModels: Set<String>): PresetConfig {
val name = json.getString("name")
val rendering = json.getJSONObject("rendering")
val models = json.optJSONArray("models")?.toList<String>() ?: emptyList()
// Validate models
models.forEach { if (!existingModels.contains(it)) throw IllegalArgumentException("Model $it not found") }
val tolerance = json.optJSONObject("tolerance")
return PresetConfig(name, rendering, models, tolerance)
}
private fun parseTestConfig(
json: JSONObject,
existingModels: Set<String>,
presets: Map<String, PresetConfig>,
defaultBackends: List<String>
): TestConfig {
val name = json.getString("name")
val description = json.optString("description")
val backends = json.optJSONArray("backends")?.toList<String>() ?: defaultBackends
val applyPresets = json.optJSONArray("apply_presets")?.toList<String>() ?: emptyList()
val rendering = JSONObject()
val combinedModels = mutableSetOf<String>()
var lastTolerance: JSONObject? = null
applyPresets.forEach { presetName ->
val preset = presets[presetName] ?: throw IllegalArgumentException("Unknown preset $presetName")
// Merge rendering (flat copy)
val keys = preset.rendering.keys()
while(keys.hasNext()) {
val k = keys.next()
rendering.put(k, preset.rendering.get(k))
}
combinedModels.addAll(preset.models)
if (preset.tolerance != null) lastTolerance = preset.tolerance
}
val testRendering = json.optJSONObject("rendering")
if (testRendering != null) {
val keys = testRendering.keys()
while(keys.hasNext()) {
val k = keys.next()
rendering.put(k, testRendering.get(k))
}
}
val testModels = json.optJSONArray("models")?.toList<String>() ?: emptyList()
combinedModels.addAll(testModels)
// Validate models
combinedModels.forEach { if (!existingModels.contains(it)) throw IllegalArgumentException("Model $it not found") }
val tolerance = json.optJSONObject("tolerance") ?: lastTolerance
return TestConfig(name, description, backends, combinedModels, rendering, tolerance)
}
}
}
data class PresetConfig(
val name: String,
val rendering: JSONObject,
val models: List<String>,
val tolerance: JSONObject?
)
private inline fun <reified T> JSONArray.toList(): List<T> {
val list = mutableListOf<T>()
for (i in 0 until length()) {
list.add(get(i) as T)
}
return list
}

View File

@@ -0,0 +1,264 @@
/*
* Copyright (C) 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.validation
import android.content.Context
import android.content.Intent
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.json.JSONObject
import java.io.File
import java.io.FileOutputStream
import java.net.HttpURLConnection
import java.net.URL
import java.util.zip.ZipFile
/**
* Handles the retrieval and preparation of test configuration and assets.
* Supports loading from:
* 1. Intent extras (local path or URL)
* 2. Default embedded assets (fallback)
*/
class ValidationInputManager(private val context: Context) {
companion object {
private const val TAG = "ValidationInputManager"
}
data class ValidationInput(
val config: RenderTestConfig,
val outputDir: File,
val generateGoldens: Boolean,
val autoRun: Boolean = false,
val autoExport: Boolean = false,
val autoExportResults: Boolean = false,
val sourceZip: File? = null
)
/**
* Resolves the test configuration based on the provided intent extras.
* This may involve extracting assets or downloading files.
*/
suspend fun resolveConfig(intent: Intent): ValidationInput = withContext(Dispatchers.IO) {
val testConfigPath = intent.getStringExtra("test_config")
val urlConfig = intent.getStringExtra("url_config")
val urlModelsBase = intent.getStringExtra("url_models_base")
val zipPath = intent.getStringExtra("zip_path")
val generateGoldens = intent.getBooleanExtra("generate_goldens", false)
val autoRun = intent.getBooleanExtra("auto_run", false)
val autoExport = intent.getBooleanExtra("auto_export", false)
val autoExportResults = intent.getBooleanExtra("auto_export_results", false)
val outputPath = intent.getStringExtra("output_path")
Log.i(TAG, "Resolving config with outputPath: $outputPath")
val baseDir = context.getExternalFilesDir(null) ?: context.filesDir
Log.i(TAG, "Base directory for resolution: ${baseDir.absolutePath}")
val outputDir = if (!outputPath.isNullOrBlank()) {
val file = File(outputPath)
val resolved = if (file.isAbsolute) {
file
} else {
File(baseDir, outputPath)
}
// Critical check: if resolved is root or very short, it's likely wrong
if (resolved.absolutePath == "/" || resolved.parent == null) {
Log.w(TAG, "Resolved outputDir is root ($resolved), defaulting to app-specific dir")
File(baseDir, "validation_results")
} else {
resolved
}
} else {
File(baseDir, "validation_results")
}
if (!outputDir.exists() && !outputDir.mkdirs()) {
Log.e(TAG, "Failed to create outputDir: ${outputDir.absolutePath}")
}
Log.i(TAG, "Final outputDir: ${outputDir.absolutePath}")
val sourceZipFile = if (zipPath != null) {
val file = File(zipPath)
if (file.isAbsolute) {
file
} else {
File(baseDir, zipPath)
}
} else {
null
}
val config = when {
sourceZipFile != null && sourceZipFile.exists() -> loadFromZip(sourceZipFile)
urlConfig != null -> downloadConfig(urlConfig, urlModelsBase)
testConfigPath != null -> ConfigParser.parseFromPath(testConfigPath)
else -> extractDefaultAssets()
}
return@withContext ValidationInput(config, outputDir, generateGoldens, autoRun, autoExport, autoExportResults, sourceZipFile)
}
suspend fun loadFromZip(zipFile: File): RenderTestConfig {
Log.i(TAG, "Unzipping validation bundle: ${zipFile.absolutePath}")
// Use a unique cache dir based on timestamp or just overwrite a common one
// Overwriting is safer to avoid filling up disk, but we must ensure we don't conflict with current run
val baseCacheDir = context.externalCacheDir ?: context.cacheDir
val cacheDir = File(baseCacheDir, "unzipped_validation")
if (cacheDir.exists()) cacheDir.deleteRecursively()
cacheDir.mkdirs()
Log.i(TAG, "Using cacheDir: ${cacheDir.absolutePath}")
ZipFile(zipFile).use { zip ->
val entries = zip.entries()
while (entries.hasMoreElements()) {
val entry = entries.nextElement()
val entryFile = File(cacheDir, entry.name)
// specific check to avoid zip slip vulnerability (though low risk here)
if (!entryFile.canonicalPath.startsWith(cacheDir.canonicalPath)) {
throw SecurityException("Zip entry is outside of the target dir: ${entry.name}")
}
if (entry.isDirectory) {
entryFile.mkdirs()
} else {
entryFile.parentFile?.mkdirs()
zip.getInputStream(entry).use { input ->
FileOutputStream(entryFile).use { output ->
input.copyTo(output)
}
}
}
}
}
// Find config.json
// We look for a file ending in .json within the unzipped structure
// Exclude results.json if it happened to be there
val jsonFiles = cacheDir.walkTopDown()
.filter { it.isFile && it.extension == "json" && it.name != "results.json" }
.toList()
if (jsonFiles.isEmpty()) throw IllegalStateException("No config.json found in zip")
// Prefer one named config.json or take the first one
val configFile = jsonFiles.find { it.name == "config.json" } ?: jsonFiles.first()
Log.i(TAG, "Parsed config from ${configFile.absolutePath}")
return ConfigParser.parseFromPath(configFile.absolutePath)
}
private suspend fun extractDefaultAssets(): RenderTestConfig {
Log.i(TAG, "Extracting default assets...")
val filesDir = context.getExternalFilesDir(null) ?: context.filesDir
val assetManager = context.assets
// Copy default_test.json
val configDir = File(filesDir, "config")
configDir.mkdirs()
val configOut = File(configDir, "default_test.json")
assetManager.open("default_test.json").use { input ->
FileOutputStream(configOut).use { output ->
input.copyTo(output)
}
}
// Copy DamagedHelmet.glb
val modelsDir = File(filesDir, "models")
modelsDir.mkdirs()
val modelOut = File(modelsDir, "helmet.glb")
assetManager.open("models/helmet.glb").use { input ->
FileOutputStream(modelOut).use { output ->
input.copyTo(output)
}
}
// Update config to point to relative path (standardizing on relative for portability where possible)
// or absolute. Here we use relative as per previous logic.
val configJson = JSONObject(configOut.readText())
val models = configJson.getJSONObject("models")
// Ensure the default model points to the extracted file
// We can use absolute path to be safe since we know where it is now.
models.put("DamagedHelmet", modelOut.absolutePath)
configOut.writeText(configJson.toString(2))
return ConfigParser.parseFromPath(configOut.absolutePath)
}
private suspend fun downloadConfig(urlConfig: String, urlModelsBase: String?): RenderTestConfig {
Log.i(TAG, "Downloading config from $urlConfig")
val filesDir = context.getExternalFilesDir(null) ?: context.filesDir
val configDir = File(filesDir, "config")
configDir.mkdirs()
val modelsDir = File(filesDir, "models")
modelsDir.mkdirs()
val configName = "downloaded_config.json"
val configFile = File(configDir, configName)
downloadFile(urlConfig, configFile)
if (urlModelsBase != null) {
val configJson = JSONObject(configFile.readText())
val models = configJson.optJSONObject("models")
if (models != null) {
val keys = models.keys()
while (keys.hasNext()) {
val key = keys.next()
val modelPath = models.getString(key)
val fileName = File(modelPath).name
val modelFile = File(modelsDir, fileName)
val modelUrl = "$urlModelsBase/$fileName"
Log.i(TAG, "Downloading model: $fileName from $modelUrl")
downloadFile(modelUrl, modelFile)
// Update config to point to absolute path
models.put(key, modelFile.absolutePath)
}
configFile.writeText(configJson.toString())
}
}
return ConfigParser.parseFromPath(configFile.absolutePath)
}
private fun downloadFile(urlStr: String, destFile: File) {
val url = URL(urlStr)
val connection = url.openConnection() as HttpURLConnection
connection.connect()
if (connection.responseCode != HttpURLConnection.HTTP_OK) {
throw Exception("Server returned HTTP ${connection.responseCode} for $urlStr")
}
destFile.parentFile?.mkdirs()
connection.inputStream.use { input ->
FileOutputStream(destFile).use { output ->
input.copyTo(output)
}
}
}
}

View File

@@ -0,0 +1,288 @@
/*
* Copyright (C) 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.validation
import android.graphics.Bitmap
import android.util.Log
import java.io.File
import java.io.FileOutputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
import org.json.JSONArray
import org.json.JSONObject
data class ValidationResult(
val testName: String,
val passed: Boolean,
val diffMetric: Float = 0f
)
class ValidationResultManager(private val outputDir: File) {
companion object {
private const val TAG = "ValidationResultManager"
}
private val results = mutableListOf<ValidationResult>()
init {
if (!outputDir.exists()) {
outputDir.mkdirs()
}
}
fun addResult(result: ValidationResult) {
results.add(result)
}
fun saveImage(name: String, bitmap: Bitmap) {
val file = File(outputDir, "$name.png")
try {
FileOutputStream(file).use { out ->
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)
}
} catch (e: Exception) {
Log.e(TAG, "Failed to save image $name", e)
}
}
fun getOutputDir(): File {
return outputDir
}
fun finalizeResults(): File? {
// Write results JSON
writeResultsJson()
return null
}
/**
* Exports a zip containing:
* - results.json
* - input test bundle (as nested zip), if provided
* - diff images (if any failure)
*/
fun exportTestResults(sourceZip: File?, timestamp: String): File? {
// Safe parent dir resolution
val parentDir = outputDir.canonicalFile.parentFile ?: outputDir.parentFile
if (parentDir == null) return null
val resultZipName = "results_$timestamp"
val zipFile = File(parentDir, "$resultZipName.zip")
Log.i(TAG, "Exporting results to ${zipFile.absolutePath}")
try {
ZipOutputStream(FileOutputStream(zipFile)).use { zos ->
// 1. Add results.json
val resultsJson = File(outputDir, "results.json")
if (resultsJson.exists()) {
zos.putNextEntry(ZipEntry("results.json"))
resultsJson.inputStream().use { it.copyTo(zos) }
zos.closeEntry()
}
// 2. Add source zip if exists
if (sourceZip != null && sourceZip.exists()) {
zos.putNextEntry(ZipEntry(sourceZip.name))
sourceZip.inputStream().use { it.copyTo(zos) }
zos.closeEntry()
}
// 3. Add diff images (any file ending in _diff.png in outputDir)
outputDir.listFiles { _, name -> name.endsWith("_diff.png") }?.forEach { diffFile ->
zos.putNextEntry(ZipEntry(diffFile.name))
diffFile.inputStream().use { it.copyTo(zos) }
zos.closeEntry()
}
}
Log.i(TAG, "Exported results to ${zipFile.absolutePath}")
return zipFile
} catch (e: Exception) {
Log.e(TAG, "Failed to export results", e)
return null
}
}
/**
* Exports a zip bundle containing:
* - Modified config.json (with updated name and relative paths)
* - Models (in models/ subdirectory)
* - Golden images (in goldens/ subdirectory)
*
* Structure:
* test_name_TIMESTAMP/
* config.json
* models/
* model.glb
* goldens/
* test_result.png
*/
fun exportTestBundle(config: RenderTestConfig, timestamp: String): File? {
Log.i(TAG, "Starting exportTestBundle for ${config.name} at $timestamp")
Log.i(TAG, "OutputDir: ${outputDir.absolutePath}")
val parentDir = outputDir.canonicalFile.parentFile ?: outputDir.parentFile
if (parentDir == null) {
Log.e(TAG, "OutputDir parent is null: ${outputDir.absolutePath}")
return null
}
Log.i(TAG, "Using parentDir for export: ${parentDir.absolutePath}")
val testNameWithTimestamp = "${config.name}_$timestamp"
val exportNameNoSpaces = testNameWithTimestamp.replace(" ", "_")
val exportDir = File(parentDir, "export_temp_$timestamp")
Log.i(TAG, "Creating export temp dir: ${exportDir.absolutePath}")
if (exportDir.exists()) exportDir.deleteRecursively()
if (!exportDir.mkdirs()) {
Log.e(TAG, "Failed to create export dir: ${exportDir.absolutePath}")
return null
}
val rootDir = File(exportDir, exportNameNoSpaces)
rootDir.mkdirs()
val modelsDir = File(rootDir, "models")
modelsDir.mkdirs()
val goldensDir = File(rootDir, "goldens")
goldensDir.mkdirs()
try {
// 1. Copy Models and update config map
val newModelsMap = mutableMapOf<String, String>()
Log.i(TAG, "Copying models...")
for ((modelName, modelPath) in config.models) {
val sourceFile = File(modelPath)
if (sourceFile.exists()) {
val destFile = File(modelsDir, sourceFile.name)
Log.d(TAG, "Copying model $modelName: $modelPath -> ${destFile.name}")
sourceFile.copyTo(destFile, overwrite = true)
// Use relative path for the new config
newModelsMap[modelName] = "models/${sourceFile.name}"
} else {
Log.w(TAG, "Model file not found: $modelPath")
}
}
// 2. Copy Golden Images
// We assume goldens are in outputDir with .png extension
Log.i(TAG, "Copying goldens from ${outputDir.absolutePath}...")
outputDir.listFiles { _, name -> name.endsWith(".png") }?.forEach { file ->
Log.d(TAG, "Copying golden: ${file.name}")
file.copyTo(File(goldensDir, file.name), overwrite = true)
}
// 3. Create modified config JSON
Log.i(TAG, "Creating config.json...")
val newConfigJson = JSONObject()
newConfigJson.put("name", testNameWithTimestamp) // Keep spaces in JSON name
// Reconstruct backends
val backendsArray = JSONArray()
config.backends.forEach { backendsArray.put(it) }
newConfigJson.put("backends", backendsArray)
// Reconstruct models
val modelsJson = JSONObject()
for ((k, v) in newModelsMap) {
modelsJson.put(k, v)
}
newConfigJson.put("models", modelsJson)
// Reconstruct tests
val testsArray = JSONArray()
for (test in config.tests) {
val testJson = JSONObject()
testJson.put("name", test.name)
if (test.description != null) testJson.put("description", test.description)
// Models for this test (set of strings)
val testModelsArray = JSONArray()
test.models.forEach { testModelsArray.put(it) }
testJson.put("models", testModelsArray)
// Rendering settings
testJson.put("rendering", test.rendering)
// Tolerance
if (test.tolerance != null) {
testJson.put("tolerance", test.tolerance)
}
// Backends (optional override)
val testBackends = JSONArray()
test.backends.forEach { testBackends.put(it) }
testJson.put("backends", testBackends)
testsArray.put(testJson)
}
newConfigJson.put("tests", testsArray)
// Write config.json
File(rootDir, "config.json").writeText(newConfigJson.toString(4))
// 4. Zip it
val zipFile = File(parentDir, "$exportNameNoSpaces.zip")
Log.i(TAG, "Zipping to ${zipFile.absolutePath}...")
ZipOutputStream(FileOutputStream(zipFile)).use { zos ->
rootDir.walkTopDown().forEach { file ->
if (file.isFile) {
val entryName = file.relativeTo(exportDir).path
zos.putNextEntry(ZipEntry(entryName))
file.inputStream().use { it.copyTo(zos) }
zos.closeEntry()
}
}
}
// Cleanup temp dir
exportDir.deleteRecursively()
Log.i(TAG, "Exported test bundle to ${zipFile.absolutePath}")
return zipFile
} catch (e: Exception) {
Log.e(TAG, "Failed to export test bundle", e)
exportDir.deleteRecursively()
return null
}
}
private fun writeResultsJson() {
val jsonArray = JSONArray()
for (result in results) {
val jsonObject = JSONObject()
jsonObject.put("test_name", result.testName)
jsonObject.put("passed", result.passed)
jsonObject.put("diff_metric", result.diffMetric)
jsonArray.put(jsonObject)
}
val jsonFile = File(outputDir, "results.json")
try {
FileOutputStream(jsonFile).use { out ->
out.write(jsonArray.toString(4).toByteArray())
}
} catch (e: Exception) {
Log.e(TAG, "Failed to write results.json", e)
}
}
}

View File

@@ -0,0 +1,313 @@
/*
* Copyright (C) 2026 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.validation
import android.content.Context
import android.graphics.Bitmap
import android.util.Log
import com.google.android.filament.utils.AutomationEngine
import com.google.android.filament.utils.ImageDiff
import com.google.android.filament.utils.ModelViewer
import org.json.JSONObject
import java.io.File
import java.io.FileOutputStream
import java.nio.ByteBuffer
class ValidationRunner(
private val context: Context,
private val modelViewer: ModelViewer,
private val config: RenderTestConfig,
private val resultManager: ValidationResultManager
) {
private var currentState = State.IDLE
private var currentTestIndex = 0
private var currentModelIndex = 0
private var currentEngine: AutomationEngine? = null
private var currentTestConfig: TestConfig? = null
private var currentModelName: String? = null
private var frameCounter = 0
enum class State {
IDLE,
WAITING_FOR_RESOURCES,
WARMUP,
RUNNING_TEST
}
interface Callback {
fun onTestFinished(result: ValidationResult)
fun onAllTestsFinished()
fun onStatusChanged(status: String)
fun onImageResult(type: String, bitmap: Bitmap)
}
var callback: Callback? = null
var generateGoldens: Boolean = false
fun start() {
if (config.tests.isEmpty()) {
callback?.onAllTestsFinished()
return
}
currentTestIndex = 0
currentModelIndex = 0
startTest(config.tests[0])
}
private fun startTest(test: TestConfig) {
currentTestConfig = test
if (test.models.isEmpty()) {
nextTest()
return
}
currentModelIndex = 0
startModel(test.models.elementAt(0))
}
private fun startModel(modelName: String) {
currentModelName = modelName
val modelPath = config.models[modelName]
if (modelPath == null) {
Log.e("ValidationRunner", "Model $modelName not found")
nextModel()
return
}
callback?.onStatusChanged("Loading $modelName for ${currentTestConfig?.name}")
// Load model on main thread (required by ModelViewer)
loadModel(modelPath)
}
private fun loadModel(path: String) {
// Assume called on Main Thread
modelViewer.destroyModel()
try {
Log.i("ValidationRunner", "Reading model file: $path")
val bytes = File(path).readBytes()
Log.i("ValidationRunner", "Loading GLB buffer... (${bytes.size} bytes)")
val buffer = ByteBuffer.wrap(bytes)
modelViewer.loadModelGlb(buffer)
Log.i("ValidationRunner", "Model loaded.")
modelViewer.transformToUnitCube()
currentState = State.WAITING_FOR_RESOURCES
frameCounter = 0
Log.i("ValidationRunner", "State set to WAITING_FOR_RESOURCES")
} catch (e: Exception) {
Log.e("ValidationRunner", "Failed to load $path", e)
nextModel()
}
}
fun onFrame(frameTimeNanos: Long) {
if (frameCounter % 60 == 0) {
Log.i("ValidationRunner", "onFrame: $currentState (frame: $frameCounter)")
}
when (currentState) {
State.IDLE -> {}
State.WAITING_FOR_RESOURCES -> {
val progress = modelViewer.progress
if (progress >= 1.0f) {
Log.i("ValidationRunner", "Resources loaded. Starting warmup.")
frameCounter = 0
currentState = State.WARMUP
}
}
State.WARMUP -> {
frameCounter++
if (frameCounter > 5) { // 5 frames warmup
startAutomation()
}
}
State.RUNNING_TEST -> {
// Log.i("ValidationRunner", "Running test...")
currentEngine?.let { engine ->
val content = AutomationEngine.ViewerContent()
content.view = modelViewer.view
content.renderer = modelViewer.renderer
content.scene = modelViewer.scene
content.lightManager = modelViewer.engine.lightManager
// Tick
val deltaTime = 1.0f / 60.0f
engine.tick(modelViewer.engine, content, deltaTime)
frameCounter++
if (engine.shouldClose()) {
Log.i("ValidationRunner", "Finishing test (frames: $frameCounter)")
// Test finished (for this spec)
currentState = State.IDLE
captureAndCompare()
}
}
}
}
}
private fun startAutomation() {
val test = currentTestConfig!!
val specJson = JSONObject()
specJson.put("name", test.name)
specJson.put("base", test.rendering)
val fullSpec = "[${specJson.toString()}]"
currentEngine = AutomationEngine(fullSpec)
val options = AutomationEngine.Options()
options.sleepDuration = 0.0f // Minimal sleep, let frames drive it
options.minFrameCount = 5 // Ensure some frames pass
currentEngine?.setOptions(options)
// Use batch mode to ensure shouldClose() works reliably
currentEngine?.startBatchMode()
currentEngine?.signalBatchMode() // Start immediately
frameCounter = 0
currentState = State.RUNNING_TEST
}
private fun captureAndCompare() {
callback?.onStatusChanged("Comparing ${currentTestConfig?.name}...")
modelViewer.debugGetNextFrameCallback { bitmap ->
compareCapturedImage(bitmap)
}
}
private fun compareCapturedImage(bitmap: Bitmap) {
val testName = currentTestConfig!!.name
val modelName = currentModelName!!
val backend = currentTestConfig?.backends?.firstOrNull() ?: "opengl"
val testFullName = "${testName}.${backend}.${modelName}"
// Golden path
val modelFile = File(config.models.get(modelName)!!)
val modelParent = modelFile.parentFile!!
// Search for golden in:
// 1. ../golden/ (standard structure)
// 2. ../goldens/ (exported structure, sibling of models)
// 3. ./goldens/ (backup)
val searchPaths = mutableListOf<File>()
modelParent.parentFile?.let {
searchPaths.add(it.resolve("golden"))
searchPaths.add(it.resolve("goldens"))
}
searchPaths.add(modelParent.resolve("goldens"))
var goldenFile: File? = null
for (path in searchPaths) {
val f = path.resolve("${testFullName}.png")
if (f.exists()) {
goldenFile = f
break
}
}
if (goldenFile != null) {
Log.i("ValidationRunner", "Found golden at ${goldenFile.absolutePath}")
} else {
Log.w("ValidationRunner", "Golden not found for $testFullName. Searched in: ${searchPaths.joinToString { it.absolutePath }}")
// Fallback to old behavior for reference if everything else fails
goldenFile = modelParent.parentFile?.resolve("golden/${testFullName}.png") ?: File("nonexistent")
}
Thread {
try {
val flipped = bitmap
callback?.onImageResult("Rendered", flipped)
var passed = false
var diffMetric = 0f
if (generateGoldens) {
val targetGolden = goldenFile ?: modelParent.parentFile?.resolve("golden/${testFullName}.png") ?: File(modelParent, "golden/${testFullName}.png")
targetGolden.parentFile?.mkdirs()
FileOutputStream(targetGolden).use { out ->
flipped.compress(Bitmap.CompressFormat.PNG, 100, out)
}
passed = true // Generating goldens always passes if successful
callback?.onStatusChanged("Golden generated")
} else {
if (goldenFile != null && goldenFile.exists()) {
val golden = android.graphics.BitmapFactory.decodeFile(goldenFile.absolutePath)
if (golden != null) {
callback?.onImageResult("Golden", golden)
val tol = currentTestConfig?.tolerance ?: org.json.JSONObject()
val tolJson = tol.toString()
val result = ImageDiff.compare(golden, flipped, tolJson, null)
passed = (result.status == ImageDiff.Result.Status.PASSED)
diffMetric = result.failingPixelCount.toFloat()
if (!passed) {
if (result.diffImage != null) {
callback?.onImageResult("Diff", result.diffImage!!)
resultManager.saveImage("${testFullName}_diff", result.diffImage!!)
}
}
} else {
callback?.onStatusChanged("Failed to load golden")
}
} else {
Log.w("ValidationRunner", "Golden not found: ${goldenFile?.absolutePath}")
callback?.onStatusChanged("Golden not found")
}
}
// Save output
resultManager.saveImage(testFullName, flipped)
val result = ValidationResult(testFullName, passed, diffMetric)
resultManager.addResult(result)
callback?.onTestFinished(result)
android.os.Handler(android.os.Looper.getMainLooper()).post {
nextModel()
}
} catch (e: Exception) {
Log.e("ValidationRunner", "Comparison failed", e)
android.os.Handler(android.os.Looper.getMainLooper()).post { nextModel() }
}
}.start()
}
private fun nextModel() {
currentModelIndex++
if (currentTestConfig != null && currentModelIndex < currentTestConfig!!.models.size) {
startModel(currentTestConfig!!.models.elementAt(currentModelIndex))
} else {
nextTest()
}
}
private fun nextTest() {
currentTestIndex++
if (currentTestIndex < config.tests.size) {
startTest(config.tests[currentTestIndex])
} else {
currentState = State.IDLE
resultManager.finalizeResults()
callback?.onAllTestsFinished()
}
}
}

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/surface_container"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintWidth_percent="0.6"
android:layout_marginTop="32dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<SurfaceView
android:id="@+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<LinearLayout
android:id="@+id/controls_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:paddingTop="20dp"
android:paddingBottom="0dp"
app:layout_constraintTop_toBottomOf="@id/surface_container"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<TextView
android:id="@+id/status_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Initializing..."
android:textSize="12sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="10dp"
android:paddingBottom="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingBottom="8dp">
<com.google.android.material.button.MaterialButton
android:id="@+id/run_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
style="@style/Widget.Material3.Button"
android:text="Run Test" />
<com.google.android.material.button.MaterialButton
android:id="@+id/load_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Widget.Material3.Button.TonalButton"
android:text="Load Test"
android:layout_marginStart="8dp"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/options_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Widget.Material3.Button.IconButton.Outlined"
app:icon="@android:drawable/ic_menu_more"
android:contentDescription="More Options"
android:layout_marginStart="8dp"/>
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/test_results_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Test Results"
android:gravity="center"
android:textSize="14sp"
android:paddingTop="0dp"
android:paddingBottom="8dp" />
</LinearLayout>
<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/controls_container"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:paddingBottom="20dp">
<LinearLayout
android:id="@+id/results_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="@+id/image_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Label" />
<ImageView
android:id="@+id/image_view"
android:layout_width="300px"
android:layout_height="300px"
android:scaleType="fitCenter"
android:background="#404040" />
</LinearLayout>

View File

@@ -1,7 +1,7 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'filament-tools-plugin'
id 'com.google.android.filament-tools'
}
project.ext.isSample = true
@@ -10,7 +10,7 @@ kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
filament {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
}

View File

@@ -0,0 +1,12 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
/.idea/caches
/.idea/gradle.xml
.DS_Store
/build
/captures
/src/main/assets
.externalNativeBuild

View File

@@ -0,0 +1,53 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'com.google.android.filament-tools'
}
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filament {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
}
clean.doFirst {
delete "src/main/assets"
}
android {
namespace 'com.google.android.filament.texturetarget'
compileSdkVersion versions.compileSdk
defaultConfig {
applicationId "com.google.android.filament.texturetarget"
minSdkVersion 26
targetSdkVersion versions.targetSdk
}
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies
// is not configuration-cache friendly yet; this is only useful for Play publication
dependenciesInfo {
includeInApk = false
}
// We use the .filamat extension for materials compiled with matc
// Telling aapt to not compress them allows to load them efficiently
aaptOptions {
noCompress 'filamat', 'ktx'
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
implementation deps.kotlin
implementation project(':filament-android')
}

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:exported="true"
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,449 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.texturetarget
import android.animation.ValueAnimator
import android.app.Activity
import android.hardware.HardwareBuffer
import android.opengl.Matrix
import android.os.Bundle
import android.view.Choreographer
import android.view.Surface
import android.view.SurfaceView
import android.view.animation.LinearInterpolator
import com.google.android.filament.*
import com.google.android.filament.RenderableManager.PrimitiveType
import com.google.android.filament.VertexBuffer.AttributeType
import com.google.android.filament.VertexBuffer.VertexAttribute
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.FilamentHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.channels.Channels
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin
class MainActivity : Activity() {
companion object {
init {
Filament.init()
}
}
private lateinit var surfaceView: SurfaceView
private lateinit var uiHelper: UiHelper
private lateinit var displayHelper: DisplayHelper
private lateinit var choreographer: Choreographer
private lateinit var engine: Engine
private lateinit var renderer: Renderer
private lateinit var scene: Scene
private lateinit var view: View
private lateinit var camera: Camera
private lateinit var triangleMaterial: Material
private lateinit var texturedMaterial: Material
private lateinit var triangleVertexBuffer: VertexBuffer
private lateinit var triangleIndexBuffer: IndexBuffer
private lateinit var quadVertexBuffer: VertexBuffer
private lateinit var quadIndexBuffer: IndexBuffer
@Entity private var triangleRenderable = 0
@Entity private var quadRenderable = 0
private var swapChain: SwapChain? = null
private val frameScheduler = FrameCallback()
private val animator = ValueAnimator.ofFloat(0.0f, 360.0f)
private var hardwareBuffer: HardwareBuffer? = null
private var texture: Texture? = null
private var renderTarget: RenderTarget? = null
private var useExternalTexture = true
private lateinit var offscreenView: View
private lateinit var offscreenCamera: Camera
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// To use set this flag with adb, run
// adb shell am start -n com.google.android.filament.texturetarget/.MainActivity --ez useExternalTexture false
useExternalTexture = intent.getBooleanExtra("useExternalTexture", true)
surfaceView = SurfaceView(this)
setContentView(surfaceView)
choreographer = Choreographer.getInstance()
displayHelper = DisplayHelper(this)
setupSurfaceView()
setupFilament()
setupView()
setupScene()
}
private fun setupSurfaceView() {
uiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK)
uiHelper.renderCallback = SurfaceCallback()
uiHelper.attachTo(surfaceView)
}
private fun setupFilament() {
engine = Engine.create()
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera(engine.entityManager.create())
offscreenView = engine.createView()
offscreenCamera = engine.createCamera(engine.entityManager.create())
}
private fun setupView() {
scene.skybox = Skybox.Builder()
.priority(0)
.color(0.0f, 0.0f, 1.0f, 1.0f).build(engine)
// This is the view that will be drawn on screen.
view.camera = camera
view.scene = scene
view.isPostProcessingEnabled = false
// This is the view that will be rendered off-screen.
offscreenView.camera = offscreenCamera
offscreenView.scene = scene
offscreenView.isPostProcessingEnabled = false
}
private fun setupScene() {
loadMaterials()
createTriangleMesh()
createQuadMesh()
// layer 1: skybox
// layer 2: triangle
// layer 3: quad
triangleMaterial.defaultInstance.cullingMode = Material.CullingMode.NONE;
texturedMaterial.defaultInstance.cullingMode = Material.CullingMode.NONE;
// The triangle is a regular renderable.
triangleRenderable = EntityManager.get().create()
RenderableManager.Builder(1)
.geometry(0, PrimitiveType.TRIANGLES, triangleVertexBuffer, triangleIndexBuffer, 0, 3)
.material(0, triangleMaterial.defaultInstance)
.culling(false)
.castShadows(false)
.receiveShadows(false)
.layerMask(7, 2)
.build(engine, triangleRenderable)
// The quad is a regular renderable.
quadRenderable = EntityManager.get().create()
RenderableManager.Builder(1)
.geometry(0, PrimitiveType.TRIANGLES, quadVertexBuffer, quadIndexBuffer, 0, 6)
.material(0, texturedMaterial.defaultInstance)
.culling(false)
.castShadows(false)
.receiveShadows(false)
.layerMask(7, 4)
.build(engine, quadRenderable)
// We only want to render the triangle in the offscreen view.
offscreenView.setVisibleLayers(7, 3) // render skybox + triangle
// We only want to render the quad in the on-screen view.
view.setVisibleLayers(7, 4) // render quad only
scene.addEntity(triangleRenderable)
scene.addEntity(quadRenderable)
startAnimation()
}
private fun loadMaterials() {
readUncompressedAsset("materials/baked_color.filamat").let {
triangleMaterial = Material.Builder().payload(it, it.remaining()).build(engine)
}
if (useExternalTexture) {
readUncompressedAsset("materials/texturedExternal.filamat").let {
texturedMaterial = Material.Builder().payload(it, it.remaining()).build(engine)
}
} else {
readUncompressedAsset("materials/textured.filamat").let {
texturedMaterial = Material.Builder().payload(it, it.remaining()).build(engine)
}
}
}
private fun createTriangleMesh() {
val intSize = 4
val floatSize = 4
val shortSize = 2
val vertexSize = 3 * floatSize + intSize
data class Vertex(val x: Float, val y: Float, val z: Float, val color: Int)
fun ByteBuffer.put(v: Vertex): ByteBuffer {
putFloat(v.x)
putFloat(v.y)
putFloat(v.z)
putInt(v.color)
return this
}
val vertexCount = 3
val a1 = PI * 2.0 / 3.0
val a2 = PI * 4.0 / 3.0
val vertexData = ByteBuffer.allocate(vertexCount * vertexSize)
.order(ByteOrder.nativeOrder())
.put(Vertex(1.0f, 0.0f, 0.0f, 0xffff0000.toInt()))
.put(Vertex(cos(a1).toFloat(), sin(a1).toFloat(), 0.0f, 0xff00ff00.toInt()))
.put(Vertex(cos(a2).toFloat(), sin(a2).toFloat(), 0.0f, 0xff0000ff.toInt()))
.flip()
triangleVertexBuffer = VertexBuffer.Builder()
.bufferCount(1)
.vertexCount(vertexCount)
.attribute(VertexAttribute.POSITION, 0, AttributeType.FLOAT3, 0, vertexSize)
.attribute(VertexAttribute.COLOR, 0, AttributeType.UBYTE4, 3 * floatSize, vertexSize)
.normalized(VertexAttribute.COLOR)
.build(engine)
triangleVertexBuffer.setBufferAt(engine, 0, vertexData)
val indexData = ByteBuffer.allocate(vertexCount * shortSize)
.order(ByteOrder.nativeOrder())
.putShort(0)
.putShort(1)
.putShort(2)
.flip()
triangleIndexBuffer = IndexBuffer.Builder()
.indexCount(3)
.bufferType(IndexBuffer.Builder.IndexType.USHORT)
.build(engine)
triangleIndexBuffer.setBuffer(engine, indexData)
}
private fun createQuadMesh() {
val floatSize = 4
val shortSize = 2
val vertexSize = (2 * floatSize) + (2 * floatSize) // position + UV
data class Vertex(val x: Float, val y: Float, val u: Float, val v: Float)
fun ByteBuffer.put(v: Vertex): ByteBuffer {
putFloat(v.x)
putFloat(v.y)
putFloat(v.u)
putFloat(v.v)
return this
}
val vertexCount = 4
val vertexData = ByteBuffer.allocate(vertexCount * vertexSize)
.order(ByteOrder.nativeOrder())
.put(Vertex(-1.0f, -1.0f, 0.0f, 0.0f))
.put(Vertex( 1.0f, -1.0f, 1.0f, 0.0f))
.put(Vertex( 1.0f, 1.0f, 1.0f, 1.0f))
.put(Vertex(-1.0f, 1.0f, 0.0f, 1.0f))
.flip()
quadVertexBuffer = VertexBuffer.Builder()
.bufferCount(1)
.vertexCount(vertexCount)
.attribute(VertexAttribute.POSITION, 0, AttributeType.FLOAT2, 0, vertexSize)
.attribute(VertexAttribute.UV0, 0, AttributeType.FLOAT2, 2 * floatSize, vertexSize)
.build(engine)
quadVertexBuffer.setBufferAt(engine, 0, vertexData)
val indexData = ByteBuffer.allocate(6 * shortSize)
.order(ByteOrder.nativeOrder())
.putShort(0).putShort(1).putShort(2)
.putShort(0).putShort(2).putShort(3)
.flip()
quadIndexBuffer = IndexBuffer.Builder()
.indexCount(6)
.bufferType(IndexBuffer.Builder.IndexType.USHORT)
.build(engine)
quadIndexBuffer.setBuffer(engine, indexData)
}
private fun startAnimation() {
animator.interpolator = LinearInterpolator()
animator.duration = 4000
animator.repeatMode = ValueAnimator.RESTART
animator.repeatCount = ValueAnimator.INFINITE
animator.addUpdateListener { a ->
val transformMatrix = FloatArray(16)
Matrix.setRotateM(transformMatrix, 0, -(a.animatedValue as Float), 0.0f, 0.0f, 1.0f)
val tcm = engine.transformManager
tcm.setTransform(tcm.getInstance(triangleRenderable), transformMatrix)
}
animator.start()
}
override fun onResume() {
super.onResume()
choreographer.postFrameCallback(frameScheduler)
animator.start()
}
override fun onPause() {
super.onPause()
choreographer.removeFrameCallback(frameScheduler)
animator.cancel()
}
override fun onDestroy() {
super.onDestroy()
choreographer.removeFrameCallback(frameScheduler)
animator.cancel()
uiHelper.detach()
// Destroy all renderables.
scene.remove(triangleRenderable)
scene.remove(quadRenderable)
// Destroy all resources.
engine.destroyEntity(triangleRenderable)
engine.destroyEntity(quadRenderable)
engine.destroyRenderer(renderer)
engine.destroyVertexBuffer(triangleVertexBuffer)
engine.destroyIndexBuffer(triangleIndexBuffer)
engine.destroyVertexBuffer(quadVertexBuffer)
engine.destroyIndexBuffer(quadIndexBuffer)
engine.destroyMaterial(triangleMaterial)
engine.destroyMaterial(texturedMaterial)
engine.destroyView(view)
engine.destroyView(offscreenView)
engine.destroyScene(scene)
engine.destroyCameraComponent(camera.entity)
engine.destroyCameraComponent(offscreenCamera.entity)
renderTarget?.let { engine.destroyRenderTarget(it) }
texture?.let { engine.destroyTexture(it) }
hardwareBuffer?.close()
val entityManager = EntityManager.get()
entityManager.destroy(triangleRenderable)
entityManager.destroy(quadRenderable)
entityManager.destroy(camera.entity)
entityManager.destroy(offscreenCamera.entity)
engine.destroy()
}
inner class FrameCallback : Choreographer.FrameCallback {
override fun doFrame(frameTimeNanos: Long) {
choreographer.postFrameCallback(this)
if (uiHelper.isReadyToRender) {
if (renderer.beginFrame(swapChain!!, frameTimeNanos)) {
// Render the triangle to the texture.
renderer.render(offscreenView)
// Render the quad to the screen.
renderer.render(view)
renderer.endFrame()
}
}
}
}
inner class SurfaceCallback : UiHelper.RendererCallback {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface, uiHelper.swapChainFlags)
displayHelper.attach(renderer, surfaceView.display)
}
override fun onDetachedFromSurface() {
displayHelper.detach()
swapChain?.let {
engine.destroySwapChain(it)
engine.flushAndWait()
swapChain = null
}
}
override fun onResized(width: Int, height: Int) {
// On-screen camera
val zoom = 1.0
val aspect = width.toDouble() / height.toDouble()
camera.setProjection(Camera.Projection.ORTHO, -aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0)
view.viewport = Viewport(0, 0, width, height)
// Off-screen camera
val offscreenZoom = 1.5
offscreenCamera.setProjection(Camera.Projection.ORTHO,
-aspect * offscreenZoom, aspect * offscreenZoom,
-offscreenZoom, offscreenZoom, 0.0, 10.0)
offscreenView.viewport = Viewport(0, 0, width, height)
// If we have a render target, destroy it.
renderTarget?.let { engine.destroyRenderTarget(it) }
texture?.let { engine.destroyTexture(it) }
hardwareBuffer?.close()
if (useExternalTexture) {
// Create a new render target.
hardwareBuffer = HardwareBuffer.create(width, height,
HardwareBuffer.RGBA_8888, 1,
HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE or HardwareBuffer.USAGE_GPU_COLOR_OUTPUT)
texture = Texture.Builder()
.width(width)
.height(height)
.usage(Texture.Usage.COLOR_ATTACHMENT or Texture.Usage.SAMPLEABLE)
.sampler(Texture.Sampler.SAMPLER_EXTERNAL)
.format(Texture.InternalFormat.RGBA8)
.external()
.build(engine)
texture!!.setExternalImage(engine, hardwareBuffer!!)
} else {
texture = Texture.Builder()
.width(width)
.height(height)
.levels(1)
.usage(Texture.Usage.COLOR_ATTACHMENT or Texture.Usage.SAMPLEABLE)
.format(Texture.InternalFormat.RGBA8)
.build(engine)
}
renderTarget = RenderTarget.Builder()
.texture(RenderTarget.AttachmentPoint.COLOR, texture!!)
.build(engine)
offscreenView.renderTarget = renderTarget
// Set the texture on the quad material.
texturedMaterial.defaultInstance.setParameter("texture", texture!!,
TextureSampler(TextureSampler.MinFilter.LINEAR, TextureSampler.MagFilter.LINEAR,
TextureSampler.WrapMode.CLAMP_TO_EDGE))
FilamentHelper.synchronizePendingFrames(engine)
}
}
private fun readUncompressedAsset(assetName: String): ByteBuffer {
assets.openFd(assetName).use { fd ->
val input = fd.createInputStream()
val dst = ByteBuffer.allocate(fd.length.toInt())
val src = Channels.newChannel(input)
src.read(dst)
src.close()
return dst.apply { rewind() }
}
}
}

View File

@@ -0,0 +1,18 @@
material {
name : baked_color,
shadingModel : unlit,
requires : [
color
]
}
fragment {
void material(inout MaterialInputs material) {
// You must always call the prepareMaterial() function
prepareMaterial(material);
// We set the material's color to the color interpolated from
// the model's vertices
material.baseColor = getColor();
}
}

View File

@@ -0,0 +1,20 @@
material {
name : textured,
shadingModel : unlit,
parameters : [
{
type : sampler2d,
name : texture
}
],
requires: [
uv0
]
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_texture, uvToRenderTargetUV(getUV0()));
}
}

View File

@@ -0,0 +1,20 @@
material {
name : textured,
shadingModel : unlit,
parameters : [
{
type : samplerExternal,
name : texture
}
],
requires: [
uv0
]
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_texture, uvToRenderTargetUV(getUV0()));
}
}

View File

@@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0"/>
<item
android:color="#00000000"
android:offset="1.0"/>
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1"/>
</vector>

View File

@@ -0,0 +1,171 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z"/>
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
</vector>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

Some files were not shown because too many files have changed in this diff Show More