Compare commits

..
Author SHA1 Message Date
Doris Wu bd073119d2 Revert "buffer update opt: Add a flag to guard the feature (#9322)"
This reverts commit 49c4a5d62c.
2025-10-15 23:41:03 +08:00
Doris Wu 06c4ed4e6b fix: material sandbox scene crashes during shutdown (#9325) 2025-10-15 15:34:50 +00:00
Doris Wu 49c4a5d62c buffer update opt: Add a flag to guard the feature (#9322) 2025-10-15 23:14:53 +08:00
Doris Wu c757cc3629 buffer update opt: Introduce BufferAllocator and its tests (#9304)
* Introduce AllocationStrategy and its tests

* feedback

* feedback

* Add stress test

* Fix the build

* Minor fix

* Rename the class

* Rename

* Make const
2025-10-15 06:25:42 +00:00
rafadevai dbdf8f672b GL: Check if GL_EXT_texture_filter_anisotropic in supported in GLES (#9317)
In GLES the anisotropic filtering featuring is always
disabled even in the cases where is supported by the hardware
because the check for the extension is missing.
2025-10-14 23:03:25 -07:00
Filament Bot 54bd888374 [automated] Updating /docs due to commit b7dea28
Full commit hash is b7dea28cc5

DOCS_ALLOW_DIRECT_EDITS
2025-10-14 21:28:53 +00:00
Benjamin Doherty b7dea28cc5 Release Filament 1.66.0 2025-10-14 14:25:20 -07:00
Benjamin Doherty 9aa8e7780b Fix NEW_RELEASE_NOTES 2025-10-14 14:24:52 -07:00
Ben Doherty 271e639abe Revert "Make check-headers test use c++20" (#9316) 2025-10-14 14:12:34 -07:00
Ben Doherty 082a79eebc Fix, revert to C++17 string_view constructor (#9315) 2025-10-13 15:01:40 -07:00
Ben Doherty 7a10c09954 Fix, Abseil compilation error with StaticString (#9314) 2025-10-13 15:01:39 -07:00
Filament Bot 3139a37cc7 [automated] Updating /docs due to commit f8e8c27
Full commit hash is f8e8c27c04

DOCS_ALLOW_DIRECT_EDITS
2025-10-13 19:56:08 +00:00
Mathias AgopianandPowei Feng f8e8c27c04 Add a Renderer API to force skipping frames (#9313)
* Add a Renderer API to force skipping frames

Renderer::skipNextFrames(size_t) can be used to force filament to
pretend the next N frames must be skipped. This is mostly useful for
debugging.

* Add DebugOptions to Settings

We still need to move the "Debug" features of gltf_viewer to this,
but this give us a framework to do it. 
Currently there is one debug option that allows to set a number of
frames to skip.

ViewerGui propose a button to skip 10 frames using this framework

* Update libs/viewer/src/Settings.cpp

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

* Update libs/viewer/src/Settings.cpp

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

---------

Co-authored-by: Powei Feng <powei@google.com>
2025-10-13 12:52:17 -07:00
Mathias Agopian c79d695ffb fix wasm build. (#9312)
The new AsyncJobQueue can't work with wasm, which doesn't support 
threads.
2025-10-13 12:18:28 -07:00
David Neto ad6f6cf149 filamat: remove call to Glslang's SPIR-V remapper (#9310)
The Glslang SPIR-V remapper was removed, and replaced by the CanonicalizeIds
pass in spirv-opt.  See https://github.com/KhronosGroup/SPIRV-Tools/pull/6174

Filament's GLSL post-optimization algorithm already runs CanonicalizeIds.

Bug: b:450891564
2025-10-13 09:46:07 -07:00
Mathias Agopian 8506e94f10 Improvements to FrameInfo (#9293)
* fix a possible deadlock in AsyncJobQueue

drainAndExit() could get stuck because it waited for the job
queue to be empty, but that was not signaled.
in fact, drainAndExit() didn't need to do that.

* Improvements to FrameInfo 

- return the GPU Complete timestamp
- return the app VSYNC timestamp
- works TimerQueries are not supported

The VSYNC time is just a convenience as it is the same value
provided by the application during Renderer::beginFrame() or via
Renderer::setVsyncTime().
2025-10-10 21:40:28 +00:00
Mathias Agopian 5db8e0b9ab fix a regression in FMaterial::setConstant() (#9308)
it used to return false when setting the same value for the constant,
which other code used to invalidate the material or not. but it
was recently changed to always return true on success.

this reestablish the previous behavior.
2025-10-10 12:43:32 -07:00
Powei Feng da55574b32 webgpu: refactor blitter to use struct as keys (#9300)
Using struct as keys simplifies the parameter definitions of the
relevant pipeline, pipelinelayout, shader module methods. This
enables adding or removing fields without adding major changes
to method definitions.

Using utils::hash::MurmurHashFn also aligns with the style of
the rest of filament.
2025-10-10 17:31:47 +00:00
yein 736fed00b3 handle StatusCode::UNSUPPORTED in << operator (#9307) 2025-10-10 00:06:57 +00:00
Evan Mezeske 9b200fc33a Some trivial changes to compile under most recent MSVC as a CMake sub-project (#9275)
* Add a workaround for Filament's breaking change to add_subdirectory for Abseil, see: https://github.com/google/filament/issues/8611

* Fix #pragma warning syntax for MSVC

* Only search for an external Abseil dependency if a new option FILAMENT_USE_EXTERNAL_ABSL is set
2025-10-09 23:06:18 +00:00
yein fa436f1d12 Make JsonishParser use utils::Status (#9302)
* Make JsonishParser use utils::Status

- add unsupported error in utils::Status
- add invalid case in the test

* return a pair of Status and string in resolveEscapes;
use initializer list for JsonishString and move that to the header.
2025-10-09 15:44:03 -07:00
Powei Feng 837b2715a0 Update MATERIAL_VERSION to 66 2025-10-09 11:29:16 -07:00
Jordan Rupprecht 1a04312986 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 https://github.com/llvm/llvm-project/commit/ebcf1bf2ecba6b25ece3c2bbddb4485e76189387.
2025-10-09 10:24:00 -07:00
Filament Bot a89711b006 [automated] Updating /docs due to commit 6d061b5
Full commit hash is 6d061b5d01

DOCS_ALLOW_DIRECT_EDITS
2025-10-08 20:04:04 +00:00
Powei Feng 6d061b5d01 renderdiff: add two params to local_test.sh (#9301)
- --no_rebuild will skip building the gltf_viewer again
 - --num_threads will limit the number of threads used in running
   the rendering test.

Both of these options are meant for debugging locally.
2025-10-08 13:01:09 -07:00
Powei Feng 53ddb3dd1c renderdiff: [viewer] enable frontend to be used with runID (#9277) 2025-10-08 18:36:30 +00:00
Powei Feng c7b0a7f441 webgpu: fix queue submission and fence (#9299)
- Add WebGPUQeuueManager to manage queue submissions
 - The manager will keep a "last status" field that will track
   the status of the last submission.
 - Any created HwFence will be associated with a status object.
 - The object updates in a callback that indicates that the
   submitted workfload has been completed.
2025-10-08 17:30:19 +00:00
Filament Bot d7b44a2585 [automated] Updating /docs due to commit caf886d
Full commit hash is caf886df6b

DOCS_ALLOW_DIRECT_EDITS
2025-10-07 22:58:22 +00:00
Powei Feng caf886df6b Release Filament 1.65.4 2025-10-07 15:54:13 -07:00
Sungun Park 287984dd7f gl: Enable shared contexts for Windows (#9298)
This change addresses a platform-specific issue on Windows where shared
OpenGL contexts must be created on the same thread as the primary
context.

To resolve this, we now pre-create a pool of shared contexts when the
driver is initialized. These contexts are then distributed to other
threads as needed, ensuring shared context creation requirement on
Windows. This allows us to be able to use THREAD_POOL mode for shader
compiler service on Windows. So Windows build uses THREAD_POOL mode
instead of ASYNCHRONOUS mode as of this change.

This change also refactors the shader compiler service to catch and
report errors in the same thread where the program compilation and
linking actually performed as it's the correct way to use shared
contexts. Otherwise it may crashes.
2025-10-07 19:30:42 +00:00
Powei Feng 3294bb64a5 Revert "Make matc workarounds default to NONE again" (#9295)
This reverts commit d11a6b4467.

Breakage detailed in following bug

BUGS=449740720
2025-10-07 18:50:34 +00:00
yeinandPowei Feng f52476a323 Use utils::Status in MaterialParser (#9285)
* Use utils::Status in MaterialParser

* Use utils::sstream instead of std::stringstream

* Remove remaining std::cerr and dep; update MaterialParser::reflectParameters

* make error message in utils::Status more generic

---------

Co-authored-by: Powei Feng <powei@google.com>
2025-10-07 11:27:11 -07:00
Powei Feng c839915a00 Add missing optional include for MaterialParser (#9296) 2025-10-06 22:50:02 -07:00
Mathias Agopian 2deafc6b81 fix matc -E (preprocessor) option (#9292)
this option was ignored and treated as -O0.
2025-10-03 20:15:05 -07:00
Powei Feng fdec0f79a2 renderdiff: [viewer] fix magnifier (#9290)
- Fix the magnifier positioning for both compare and standalone
   mode. Simplified a lot of the logic and streamlined passing
   of states between components.
- Slight css adjustments
2025-10-03 21:44:53 +00:00
Mathias Agopian 31d66002a9 optional per-channel depth clear (#9287)
- increase the number of channels from 4 to 8
- new api on View to enable per-channel depth clear
FIXES=[447648764]
2025-10-03 14:25:02 -07:00
Mathias Agopian f2ed382cf1 New ImmutableCString string class (#9291)
ImmutableCString is a string class similar to CString except it's
immutable. ImmutableCString occupies 16 bytes instead of 8 for CString.

However, ImmutableCString is able to avoid memory allocation when
constructed from a string literal, and in that way it us similar
to StaticString.

ImmutableCString can be auto converted from StaticString.

The backend tag tracking is updated to use ImmutableCString and
the FrameGraph resource manager us updated to use StaticString.

Together these changes significantly cut down heap allocations due to
internal tagging.


We also add optional tracking to {Immutable}CString.
2025-10-03 14:23:36 -07:00
yein a4746eab0c Minor changes in utils::Status (#9288)
* Minor changes in utils::Status

- << operator doesn't have to be friend
- simplify getErrorMessage to not use strlen internally

* Replace std::ostream to utils::io::ostream
2025-10-03 12:53:46 -07:00
Filament Bot 0b011fae7d [automated] Updating /docs due to commit a6c9922
Full commit hash is a6c9922d33

DOCS_ALLOW_DIRECT_EDITS
2025-10-03 18:40:22 +00:00
Eliza a6c9922d33 internal: fix some editor indentation rules (#9289)
* internal: fix some editor indentation rules

* internal: update CODE_STYLE.md
2025-10-03 11:38:01 -07:00
Eliza 7fe1ee3fd5 utils: RefCountedInternPool/RefCountedMap (#9284)
* utils: RefCountedInternPool/RefCountedMap

First, introduce RefCountedInternPool, a reference counted intern pool of
Slice<const T>. Just acquire() a slice that you want and you're guaranteed to
get exactly one canonical value-equal Slice<const T> back.

Additionally, introduce the concept of NullValue to RefCountedMap. A NullValue
defines what should be considered an uninitialized value; by default, it's the
default value of that type (0 for ints, nullptr for pointers, etc). This allows
us to lazily-initialize values in the map. A client can acquire() a bunch of
different resources which will be initialized only when get(factory) is called.
If a client attempts to get() a value without specifying a factory, and the
value is not initialized (i.e. equal to NullValue{}()), RefCountedMap will
panic.

* utils: add unit tests for ref-counted collections

* utils: remove C++20 features, fix memory issue

* utils: remove RefCounted from InternPool
2025-10-03 11:21:02 -07:00
Eliza 075726db8b engine: change spec constants to simple list (#9283)
* engine: change spec constants to simple list

For a shader program cache to be keyed on the set of spec constants that a
program has set, we need to know full exact list of constants, including their
default values. If we're going to always hold a list of all constants all the
time, then we may as well store them as a simple list where each index is the ID
number of the spec constant.

As part of this change, we now write the default values of spec constants into
the material file metadata.

* fix indent

* engine: fix sRGB swapchain emulation
2025-10-02 23:48:11 +00:00
Mathias Agopian b22ff3bebb fix exceptions (#9281) 2025-10-02 16:22:01 -07:00
Sungun Park bc794bbf7b Fix public headers check on github (#9286) 2025-10-01 23:36:26 -07:00
Sungun Park 9c29c3d192 Fix memory leaks for xlib (#9282)
This change frees memory returned by `glXGetFBConfigs` and
`glXChooseFBConfig` using `XFree`.
2025-10-01 23:09:55 +00:00
Eliza 8e5dabfa8e utils: split Slice into mutable and constant types (#9276)
* slice: fix memory semantics

* slice: prefer passing slice by value

This lets us do nice things like coercing Slice<T> to Slice<const T>, etc.

* slice: fix unit tests

* slice: fix copy/assignment, hash function

Don't attempt to define a copy constructor/assignment operator which would
convert a constant type to a mutable type.

Additionally, fix the hash function such that we're hashing U instead of const
U.
2025-10-01 22:40:50 +00:00
Mathias Agopian e974989a95 new utility AsyncJobQueue (#9278)
* new utility AsyncJobQueue

this is a very simple job queue, it spawns a thread and runs the jobs
pushed to the queue in sequence.

* use AsyncJobQueue in OpenGLTimerQuery
2025-10-01 14:54:34 -07:00
yein 057ce2ea4b Introduce utils::Status (#9279)
* Introduce utils::Status

* Replace std::string with utils::CString in utils::Status

* Update unit tests
2025-10-01 14:53:51 -07:00
Martin Valgur 2e920f2780 Fix an invalid USE_EXTERNAL_GLES3 define (#9280)
Should be FILAMENT_USE_EXTERNAL_GLES3 to match its usage in code.
2025-10-01 10:59:55 -07:00
Mathias Agopian b41e6dfd5c fix several issues CircularQueue (#9271)
- pop_back() didn't call the object's dtor
- added a dtor so objects can't be leaked
- made it moveable but not copiable
- added unit tests
2025-09-30 16:06:58 -07:00
Filament Bot 8413c84284 [automated] Updating /docs due to commit 10e63bf
Full commit hash is 10e63bf2cf

DOCS_ALLOW_DIRECT_EDITS
2025-09-30 21:44:09 +00:00
Powei Feng 10e63bf2cf renderdiff: [viewer] add Run ID as a way to pull artifacts (#9272)
The viewer supports pulling artifacts based on PR number, and now
we support providing Run ID as an alternative to identify the
renderdiff run on Github CI.
2025-09-30 21:32:36 +00:00
Filament Bot 73ba8fc753 [automated] Updating /docs due to commit f07a44e
Full commit hash is f07a44eb15

DOCS_ALLOW_DIRECT_EDITS
2025-09-30 18:53:20 +00:00
Sungun Park f07a44eb15 Release Filament 1.65.3 2025-09-30 18:50:39 +00:00
Sungun Park 3dc3c78901 Support C++17 for RefCountedMap (#9274)
Some of our users are sticking to C++17 for a while.
2025-09-30 11:45:51 -07:00
Sungun Park db099033e8 Fix compile issues (#9273) 2025-09-30 10:48:35 -07:00
lyriccoder 14a460961c Signal handler calls non-async-safe function (std::cout) (#9227)
In the current implementation, the function std::cout is used inside a                                                                                                                                                                signal handler. This is problematic because std::cout is not
async-signal-safe. According to POSIX standards, only a small set of
functions are guaranteed to be safe when called from signal handlers,
and std::cout is not one of them. Using non-async-signal-safe functions
inside signal handlers leads to undefined behavior and can cause
crashes, deadlocks, or other unpredictable issues.

By making these changes, we avoid undefined behavior and ensure the
program can handle signals safely.
2025-09-30 00:23:09 -07:00
Mathias AgopianandPowei Feng b467690ac7 new fenceWait() API in the backend (#9267)
* new fenceWait() API in the backend

* correct implementation of fenceWait() for GL and WebGPU

- fenceWait() now works correctly if called before the fence is
  created on the backend side

- the STL's condition wait_for() is actually a wait_until, which
  means we have to make sure now() + timeout doesn't overflow.

- also we make sure to keep a reference to the fence internal state
  while we wait so that we're safe if it's destroyed during that time.

* Implement fenceWait() properly on vulkan


On Vulkan, unfortunately, the implementation is complicated, as we
need three levels of "wait".

First we need to wait using a mutex/condition that the shared fence
is created (this is because on vulkan, all HwFence share the same
"state" associated to the same command buffer).

Once we have that, we need to wait for the VkFence to be submitted,
this is done using a read/write lock and condition variable. The
read/write lock is not needed at this stage, but in the next.

Once the fence is submitted, we can now wait using vkWaitForFences,
however, external host synchronization is needed. Multiple 
vkWaitForFences can be issued together (and use the read lock), but
must be mutually exclusive with vkResetFences and vkQueueSubmit.
By construction, we know that this can't happen during vkQueueSubmit
due to the "2nd level" of wait, however we need to prevent
simultaneous calls to  vkResetFences, this is done using a write lock.

By construction, we're guaranteed that when vkResetFences is called,
the fence has signaled, we just need to wait for all vkWaitForFences to
return.

A side effect of this change is that fenceGetStatus() has a better
implementation, since it's just a wait with timeout of 0.

* Update filament/backend/src/vulkan/VulkanDriver.cpp

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

---------

Co-authored-by: Powei Feng <powei@google.com>
2025-09-29 13:09:43 -07:00
Mathias Agopian b02bb0eaf6 assert sampler function only when it's not NONE.
FIXES=[437172017]
2025-09-29 13:08:54 -07:00
Sungun Park 436dffcbb3 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-27 00:03:32 -07:00
Mathias Agopian 95935b38bc enable timer queries on Mali drivers known to be good
FIXES=[273759031]
2025-09-27 00:02:09 -07:00
Powei Feng 0fa3de5ac7 renderdiff: add magnification glass of rendering (#9265)
- Show magnifying glass when diffing between two images
- Add checkbox to enable or disable feature
2025-09-27 00:19:26 +00:00
Powei Feng d8e8aafad7 vk: fix VulkanPlatform CString usage (#9266) (#9260)
Since #9259, CString in VulkanPlatform fall into the literal
constructor path. But we really want the null-terminated
(char const*) path.  So we cast the strings to (char const*)
to enforce null-teriminated behavior.

RDIFF_BRANCH=pf/renderdiff-add-tolerance
2025-09-26 23:42:56 +00:00
Powei Feng 33a4ab3d88 vk: fix VulkanPlatform CString usage (#9266)
Since #9259, CString in VulkanPlatform fall into the literal
constructor path. But we really want the null-terminated
(char const*) path.  So we cast the strings to (char const*)
to enforce null-teriminated behavior.
2025-09-26 15:37:33 -07:00
rafadevai bcaf5e9da5 VK: Allow memcpy of vertex/index static buffers in UMA (#9258)
* VK: Allow memcpy of vertex/index buffers in UMA

- Renamed VulkanBufferUsage to VulkanBufferBinding
to avoid confusion with the BufferUsage enum.
- In UMA all buffers are persistently memory mapped.
- In the case of static buffers that are memory mapped
use memcpy directly to update their contents.

* PR Comments
2025-09-26 14:07:00 -07:00
Mathias Agopian 98f8c93950 in-place CString replace when possible 2025-09-26 08:07:55 -07:00
Mathias Agopian d11a6b4467 Make matc workarounds default to NONE again 2025-09-25 16:37:50 -07:00
Mathias Agopian 91d4e0e688 Workaround a rendering corruption on Mali
The corruption seems to be triggered with a combination of using:
- spirv-opt
- RGBA16F (as opposed to e.g. RGBA8)
- framebuffer_fetch

In this CL we disable framebuffer_fetch for drivers we know have the
issue.

FIXES=[445721121]
Fix #7794
2025-09-25 16:37:50 -07:00
Mathias Agopian 8af1cb3489 fix build warning (#9263) 2025-09-25 16:37:24 -07:00
Filament Bot 456ae4cabe [automated] Updating /docs due to commit f233b20
Full commit hash is f233b20427

DOCS_ALLOW_DIRECT_EDITS
2025-09-25 21:20:43 +00:00
Powei Feng f233b20427 renderdiff: add a filter option for local testing (#9257)
This option will allow for rendering and comparing a single
image or files that match a wildcard-style string.

README.md has been updated
2025-09-25 21:18:35 +00:00
Mathias Agopian a1b825b5b4 performance improvements to CString (#9259)
- make sure CString("foo") calls the literal constructor
- avoid memory allocations when comparing to a literal
2025-09-25 13:57:53 -07:00
Powei Feng f9beffe3dc vk: add pool for VkSemaphore for re-use and lifetime tracking (#9254)
- Add a VulkanSemaphore ref-counted class to track the references
   of a semamphore - i.e. in a command buffer or in a present.
 - Add a VulkanSemaphoreManager class to keep a pool of
   VkSempahores for better re-use.

This fixes a validation error where we were re-using a semaphore
that is associated with a command buffer while its being used
in a present (as a wait signal).
Error ris VUID-vkQueueSubmit-pSignalSemaphores-00067
2025-09-25 13:39:25 -07:00
Mathias Agopian db96b262a2 fix another matdbg build breakage (#9255) 2025-09-24 23:13:10 -07:00
Eliza c0ab447ef7 material cache: address comments (#9253)
* material cache: address comments

* material cache: simplify CRC32 comparison

* material cache: == if same address

* material cache: use plain type for cached crc32
2025-09-24 17:00:14 -07:00
rafadevai 855a8f0b49 Refactor backend getShaderLanguage functions. (#9204)
Allow returning a list of supported shader languages
instead of only one.

Notify the backend which is the preferred language.
In the case of metal, the preferred language will be
the first element in the list.

This change will allow a backend to support multiple
languages as needed, in the case of the noop driver,
it will support a material with any shader languages.
2025-09-24 16:23:42 -07:00
Mathias Agopian 9c455e856d Fix matdbg build 2025-09-24 14:36:55 -07:00
Filament Bot 009de921e2 [automated] Updating /docs due to commit 7663ca8
Full commit hash is 7663ca8dfe

DOCS_ALLOW_DIRECT_EDITS
2025-09-24 18:55:45 +00:00
Powei Feng 7663ca8dfe Release Filament 1.65.2 2025-09-24 11:53:16 -07:00
Powei Feng ee51c054b9 gl: disable fb fetch for llvmpipe (#9240) 2025-09-24 11:47:19 -07:00
Mathias Agopian 884b7590cb Update remote UI (#9247) 2025-09-24 09:53:49 -07:00
Powei Feng decf316802 Make check-headers test use c++20 2025-09-23 21:28:37 -07:00
Eliza 5516cd92e7 materials: introduce MaterialCache (#9205)
* materials: introduce MaterialCache

Presently, Filament Materials are instantiated by first parsing a bunch of
read-only data from a material file, then applying a bunch of options from its
Builder before settling on a final, immutable Material object. If two different
Material instances need to be parameterized differently, e.g. setting their spec
constants independently, each has to do all of these steps independently for
each variation.

This change introduces two new concepts: MaterialDefinition, representing the
deserialized, read-only state of a material file, and MaterialCache, a
reference-counted system responsible for managing the lifetimes of
MaterialDefinitions. Now, each Material asks the cache if a MaterialDefinition
exists for the particular UUID of the data it's trying to read; if not,
MaterialCache creates a new entry transparently. If a hundred different
Materials all try to load the same material data, only one
MaterialDefinition (and its associated GPU resources) will be created.

This first PR is the least possible invasive implementation of this feature.
There are a lot of room for improvements (and more planned). For example, each
Material still manages its own compiled shader program cache, but we can easily
move this to the MaterialCache in future PRs, further enabling the planned
mutable spec constants feature.

Additionally, there's room here to add a Material::toBuilder() method, which
could take an extant material and create a Builder object from it already
parameterized with all of the same options, a la the prototype design pattern.

* material cache: key on crc32

* material cache: make materialParser private

* move RefCountedMap to utils and add unit tests

* material cache: make create functions private

* material cache: fix broken tests on iOS/web

* material cache: address more comments
2025-09-24 00:35:59 +00:00
Mathias Agopian 77d6092890 Fix build. broken due to a bad merge (#9249) 2025-09-23 17:14:28 -07:00
Mathias Agopian 4ad619439a use RG32UI for picking instead of RG32F (#8917)
The reason for this is that according to the GLES 3.0 spec, RG32UI is 
guaranteed to be supported for writing, unlike RG32F.

We also use RGBA_INTEGER / UINT for readPixels() which is also a
guaranteed format.

Attempt to Fix #8762
2025-09-23 16:20:57 -07:00
Mathias Agopian 143d59a991 add support for memory mapped buffers in the backend (#9217)
* reorder backend methods

* add new "shared" buffer APIs to backends

We add the equivalent of GL's glMapBufferRange. The new APIs are:
- new "SHARED" flags when creating a BufferObject 
- a new HwMemoryMappedBuffer handle
- mapBuffer() maps a range of the buffer to memory
- unmapBuffer() unmaps the range
- copyToMemoryMappedBuffer() is basically a deferred memcpy, where the
  destination is a HwMemoryMappedBuffer and the source is a
  BufferDecriptor

The actual implementation doesn't have to actually map/unmap the range
on mapBuffer/unmapBuffer. e.g. on Vulkan these method are used mostly
to set offsets (for copyToMemoryMappedBuffer) and trigger the necessary
synchronizations.

Added some basic unit tests.

* add basic support for MemoryMappedBuffer in vk and metal

we implement copyToMemoryMappedBuffer() by calling updateBufferObject(),
which is enough to satisfy the API (And pass the tests).
2025-09-23 16:15:28 -07:00
Mathias Agopian 2a62518e5c imgui: new readme and update script 2025-09-23 16:13:37 -07:00
Powei Feng edb17200d0 android: fix hello-cam sample appID
Make the application id and namespace consistent.
2025-09-23 16:10:39 -07:00
Ben Doherty 2afd0bd7f7 Metal: add debug labels to Metal resources (#9187) 2025-09-23 10:57:15 -07:00
Ben Doherty bf2459540e Add Java bindings for setFrameScheduledCallback (#9182) 2025-09-22 18:40:42 -07:00
Powei Feng 09bb9828a2 Update .gitignore for renderdiff deps (#9242) 2025-09-22 21:40:20 +00:00
Sungun Park 8fda29657a Cache isMSAASwapChainSupported() result for EGL (#9235)
This change introduces a caching mechanism to store the results of MSAA
support queries.
2025-09-22 14:10:08 -07:00
Ben Doherty c53195fa9a Fix frame scheduled callbacks not being latched (#9243) 2025-09-22 14:08:20 -07:00
Powei Feng 1e59032396 vk: guard export fence creation 2025-09-22 12:36:44 -07:00
Ben Doherty 9e79be419d Metal: log command buffer errors (#9224) 2025-09-22 12:10:30 -07:00
Powei Feng a81d3217e7 github: make linux machines consistent (#9241) 2025-09-22 11:20:23 -07:00
Powei Feng aa67faefab vk: remove renderstandalone workaround (#9236)
The bug might have been addressed by PR #8952. This workaround
is no longer needed.
2025-09-22 05:38:06 +00:00
Mathias Agopian e982d8a3c6 pass backend tags by && reference
This saves a CString copy on the backend side and this forces the
frontend to make a copy explicitly.

In theory the CString should now ever be copied just once.
2025-09-19 15:25:31 -07:00
Mathias Agopian 9267563af2 fix clang-tidy warnings 2025-09-19 15:25:31 -07:00
Filament Bot 333d01a0a5 [automated] Updating /docs due to commit 24a6bd3
Full commit hash is 24a6bd30f9

DOCS_ALLOW_DIRECT_EDITS
2025-09-19 15:46:12 +00:00
Sungun Park 24a6bd30f9 Release Filament 1.65.1 2025-09-19 15:42:25 +00:00
Sungun Park fdc0bc472d Revert workaround default to ALL (#9233)
This makes artifacts on certain mobile devices. Revert them back to ALL.

BUGS=[445721121]
2025-09-18 23:45:08 -07:00
Mathias Agopian a791665a2c remove the limit to 48 material parameters
FIXES=[445698638]
2025-09-18 17:28:20 -07:00
Powei Feng 20fcce13a4 docs: fix broken renderdiff link 2025-09-18 14:52:17 -07:00
Powei Feng 8233ab1cda Revert "[automated] Updating /docs due to commit 60df8ac"
This reverts commit 656a4b6f32.
2025-09-18 14:40:07 -07:00
Filament Bot 656a4b6f32 [automated] Updating /docs due to commit 60df8ac
Full commit hash is 60df8ac6b8

DOCS_ALLOW_DIRECT_EDITS
2025-09-18 21:32:03 +00:00
Powei Feng 60df8ac6b8 renderdiff: enable webgpu and improvements (#9219)
- Allow for presets to override selected models when presented
   in order.
 - Add 'gltf' for model search path
 - Add a few simple gltf models to the 'base' preset
 - Improve UI so that missing tests do not generate any html
   bits.
 - Add documentation on using the viewer
 - Add renderdiff documentation to the project webpage.

RDIFF_BRANCH=pf/renderdiff-enable-webgpu
2025-09-18 21:29:00 +00:00
Ben Doherty 1fb3d48e90 Fix Metal LoadImageTest.UpdateImageMipLevel (#9229) 2025-09-18 13:57:36 -07:00
Powei Feng b47110c339 backend: fix read pixels test for vk (#9223)
- The vk readPixels relies heavily on DataReshaper to transform
   the output into the client's requested format. We make
   additions to the DataReshaper to address previously unavailable
   features:
     - A copy for half floats - Assuming input and output are
       both half floats.  We just do memcpy.
     - Reshaping with respect to PixelBufferDescriptor's top and
       left parameters.
 - On the test side, we do a bit of clean-up and add the ability
   to export image correctly when the PBD has dimensions different
   from the readRect and/or non-zero offsets.
 - Also re-enable two LoadImage tests.
2025-09-18 19:53:19 +00:00
Mathias Agopian 10f4632c88 small math::mat3f to GL mat3 optimizations 2025-09-18 12:15:56 -07:00
Mathias Agopian 6dbd702bb5 fix OpenGL backend tests on macOS
multi-sampled textures are only supported at feature level 2, but
on macOS OpenGL is only feature level 1.
2025-09-17 18:11:51 -07:00
Powei Feng 0dd1d3211b backend: fix scissor viewport region test (#9220)
Make sure that the rendertarget dimensions matches the texture
dimensions. Update the expected image for the test.

Also fixed usage, rendertarget parameters to make sure vk does
not have any validation errors.
2025-09-17 21:58:50 +00:00
Filament Bot 33249c6eb8 [automated] Updating /docs due to commit 59f19ae
Full commit hash is 59f19aee0e

DOCS_ALLOW_DIRECT_EDITS
2025-09-16 17:44:15 +00:00
Ben Doherty 59f19aee0e Add documentation and script to publish to Maven Central (#9216) 2025-09-16 13:41:06 -04:00
Sungun Park 06c8fc39c2 Update MATERIAL_VERSION to 64 2025-09-16 10:08:23 -07:00
Powei Feng a36ad004b7 renderdiff: add ability to diff arbitrary rendered images (#9211)
Add a way to show the difference between two rendererd image.
This is a convenience feature to see the differences between
backends.

Refactor the ExpandedFailedResult to use this new view.
2025-09-16 00:27:42 +00:00
Ivan Mikhalchuk 6ac5f26bb5 fix UB in AtomicFreeList::push and FreeList::push: access to non-static data member without proper lifetime management 2025-09-15 08:50:02 -07:00
Powei Feng bce8320f06 vk: make sure default render target is not removed (#9213)
We need to have an reference to the default render target for
the duration of the backend lifetime.  So even if the client
tries to destroy the default render target, we don't actually
destroy it.

Note that it will be destroyed on driver shutdown.
2025-09-12 22:52:21 +00:00
Powei Feng f3a4e21fe5 backend: fix blit tests for vulkan
- The rendertarget layer count should be >=1.
- Add read pixels usage bit
2025-09-12 15:27:49 -07:00
Powei Feng 6838d8602e github: fix caching for vulkansdk and mac brew (#9203)
We should be able to use ~ (tilde) to indicate the user root
directory.

Before the cache didn't work because these paths weren't found.
2025-09-12 17:54:52 +00:00
Powei Feng fe9033c7db backend: fix vulkan test with readPixels (#9202)
filament/backend/test/Workarounds.h has a specific workaround
with regards to readPixels and texture usage.  Originally this
was introduced for the WebGPU backend. This is needed
for the vulkan backend as well.

Also simplify BufferUpdatesTest.BufferObjectUpdateWithOffset
 - no need to call flush() or executeCommands(), these are
   called when the test terminates.
 - layerCount for a rendertarget should be at least 1.
2025-09-12 17:25:28 +00:00
Powei Feng 480b0878d7 vk: fix validation warnings (#9207)
- Remove extensions that have been promoted to 1.1
- Use vkCreateMetalSurfaceEXT instead of the deprecated
   vkCreateMacOSSurfaceMVK
2025-09-11 23:59:25 +00:00
Sungun Park 57d1a6a165 Add MSAA swapchain support (#9196)
Users can now create a swapchain with MSAA support, which enables direct
rendering to a multi-sampled swapchain image and automatic resolution.

This is only supported by EGL(Android). Other GL platforms (GLX, WGL,
etc) don't support it because the swapchain MSAA settings must be
configured before window creation.

Support for other backends will follow.

BUGS=[433327615]
2025-09-11 21:29:06 +00:00
Ben Doherty fe81493052 Fix g3 build (#9209) 2025-09-11 16:28:03 -04:00
Mathias Agopian 9c52ec32ff hybrid instancing improvements
Hybrid (InstanceBuffer based) instancing no longer needs a 
descriptor-set per object because we now use the same UBO for all
objects, so the "shared" per-object descriptor-set can be used.

This also implies that InstanceBuffer doesn't need to track the UBO
handle anymore, only its offset in the buffer.
2025-09-11 12:13:47 -07:00
Mathias Agopian 5cf091220c 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-11 12:13:47 -07:00
Powei Feng f6892a111c vk: fix VulkanDriver::finish() (#9199)
VulkanDriver::finish() seems like it is waiting for all the
commands to be processed, but in reality, the present calls
are not waited on (because commands->wait() only waited on
the command buffers).

Here we just call vkQueueWaitIdle to address that case.

This fixes a validation error that occurs when running the
backend test BackendTest.MissingRequiredAttributes.
2025-09-11 19:02:07 +00:00
Sungun Park 63f877a68e Fix: Correctly handle unsupported SwapChain flags (#9208)
FSwapChain initialization logic would filter out unsupported flags but
would incorrectly use the original, unfiltered flags when creating the
swap chain.

This commit ensures the filtered flags are passed to the driver. It also
adds the warning to log which ones are removed.

BUGS=[433327615]
2025-09-11 18:24:02 +00:00
Powei Feng 3d8fb3bcea vk: fix blitDEPRECATED implementation (#9201)
blitDEPRECATED can also be used in the context of a multisampled
texture resolve. Fix that case to use the resolve() path in the
VulkanBlitter.

Also fixed backend test BlitTest.ColorResolve to add the correct
usage bit (otherwise it'd have validation error).

FIXES=417229577
2025-09-11 16:48:50 +00:00
Anish Goyal e218eca6b0 Create exportable Syncs (fences) (#9110)
* Create exportable fences on Android

Also - create a conversion method for the driver api so that a fence can
be converted to an external handle, where available.

* Create a frontend API for external fences

Fences will be called 'Sync' on the frontend, and come with a method for
conversion to an external sync. This will typically be a file
descriptor, for use in posix systems.

* Refactor Sync to rely on opaque handles

Also - push the callback invocations into the backend, such that they
are scheduled on a worker thread, and not run on the Filament backend
thread.

* Address PR comment - minor refactor

Clear vectors after they've been consumed, and update null checks by
removing explicit reference to nullptr.

* Remove convertSyncToFd from non-android

Other platforms might have other handle types.

Also - remove unused header include

* Add logging for convert to fd

Also, remove duplicate includes

* Address PR - change fd type

As per request by rafadavi@, changed to match the Android spec for file
descriptor type, which is `int`.

* Address PR - remove vtable from sync

Also - rename derived sync classes

* Address comment - make SyncCallbackData private

It's technically implementation-specific, even though it currently
happens to be the same. Separate this into the different backends.

* Add stub for metal backend for sync

* Add stub impl for Sync in WebGPU
2025-09-11 09:02:56 -07:00
Powei Feng 17b8b9ff65 backend: fix MRT test's layercount (#9200)
layercount should be at least 1. This was causing a validation
error for the vk backend when running the test.
2025-09-10 15:34:15 -07:00
Powei Feng 49b8a17b1f 3p: remove spirv-tools targets for binaries and shared libs (#9198)
We need to modify spirv-tools existing CMakeLists.txt to make
sure that its binaries and libs are not included in the filament
installed output.

This change was present before, but overwritten when spirv-tools
updated (wrt the WebGPU project).

In addition to modifying the CMakeLists.txt, we add a script to
carry out the changes automatically when running the update script
in the future.

Fixes #9168
2025-09-10 20:01:42 +00:00
rafadevai f89c105941 VK: Fix leak in VulkanExternalImageManager (#9194)
In the cases of a descriptor set being updated
with a external sampled texture but that descriptor
set doesn't get used later on for rendering.

Their corresponding entry in VulkanExternalImageManager::mSetBindings
will never get removed until the application is terminated, causing
performance issues or a fatal crash if run long enough.

The expectation is that the amount of bindings with
external samplers is low or none, so this won't cause
any regression when not using external samplers.
2025-09-10 17:08:14 +00:00
Filament Bot 3d9da8ab3b [automated] Updating /docs due to commit da315ef
Full commit hash is da315ef9fe

DOCS_ALLOW_DIRECT_EDITS
2025-09-10 00:19:44 +00:00
Benjamin Doherty da315ef9fe Release Filament 1.65.0 2025-09-09 17:15:42 -07:00
Powei Feng c5a7c39c8a Remove unecessary assert on texture format + mipmappable (#9193)
The backend call `isTextureFormatMipmappable` indicates whether
a format can be used to generate bitmap through graphics API.

(The issue is that previously there was a check to validate
 whether a format is mipmappable and levels > 1. These two
 conditions do not need to imply one another.)
2025-09-08 17:14:32 -07:00
Yein Jo ff4be0be48 Lift the logic to resolve inclues in shader to MaterialCompiler
- Move the file check & dir resolution to MaterialCompiler
- Move DirIncluder back to matc
FIXES=440579712
2025-09-08 10:37:16 -07:00
Mathias Agopian 88e4ddeec7 View::setCamera() should accept nullptr
FIXES=[441757817]
2025-09-08 07:56:47 -07:00
Filament Bot 220119d855 [automated] Updating /docs due to commit 81a51ae
Full commit hash is 81a51ae7e7

DOCS_ALLOW_DIRECT_EDITS
2025-09-08 06:53:30 +00:00
Mathias Agopian c4f083cfba matc and MaterialBuilder workaround options NONE by default
The workaround option is now set to none by default. Use

```
matc -Wall
```

if you want to restore the previous behavior.

Current material workarounds:
- remove MergeReturnPass (except on Metal)
- remove SimplificationPass (except on Metal)

There are reason to believe these workarounds are no longer needed,
due to changes in spirv-opt.

It's possible that older devices might still need them.

These workaround affect *all* devices, this is why it is important
to disable them if not needed.
2025-09-07 23:52:14 -07:00
Sungun Park 81a51ae7e7 Update material doc for new APIs (#9191) 2025-09-07 23:47:28 -07:00
Mathias Agopian 4089484b46 add InstanceBuffer::getLocalTransform(size_t)
FIXES=[442918117]
2025-09-05 09:51:06 -07:00
Mathias Agopian 26ceaebac6 add RenderManager::getInstanceCount()
FIXES=[442916683]
2025-09-05 09:51:06 -07:00
Yrom c72ddfcf7a backend: use VirtualAlloc for creating soft CircularBuffer on Windows 2025-09-04 13:08:37 -07:00
Sungun Park b31a42a1d0 Improve getEyeFromViewMatrix() (#9184)
Make the size of PerViewUib 2KiB again.

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

BUGS=[441127971]
2025-09-04 18:58:14 +00:00
Mathias Agopian 76e36cd87b try to cleanup android libraries cmake build
- make as many library deps private as possible
- try to keep the same structure between the CMakeList.txt files
- for gltfio use libgltfio_core.a
2025-09-04 11:28:28 -07:00
Mathias Agopian 60da554732 draco: fix c++20 warnings 2025-09-04 11:27:47 -07:00
Mathias Agopian 5613663686 create an update script for draco and update readme
note that updating to a recent version is still difficult because
of makefile changes. we can do that later.
2025-09-04 11:27:47 -07:00
Mathias Agopian 57e308b75f fix linear fog parameters calculation
FIXES=[442852042]
2025-09-04 11:27:27 -07:00
Mathias Agopian d07c15dfc6 zbloat: modernize script
The script uses os.system to execute external commands like nm and 
objdump. Instead we use the subprocess module, which is the recommended 
approach in modern Python. 
Properly handle potential errors if nm or objdump fail.
2025-09-04 08:37:18 -07:00
Mathias Agopian 1422116242 zbloat: fix warnings 2025-09-04 08:37:18 -07:00
Mathias Agopian 28fcbe2b77 zbloat: add support for .a 2025-09-04 08:37:18 -07:00
Ben Doherty 2535d1b5d9 Implement setFrameScheduledCallback on other backends (#9177) 2025-09-04 11:09:26 -04:00
Mathias Agopian 4c91d48ed3 Revert "use fmin/fmax for floating-point"
This reverts commit a032190b24.
2025-09-04 00:08:30 -07:00
Mathias Agopian a032190b24 use fmin/fmax for floating-point
On ARM this generates the fmin/fmax instruction, which avoids
branches.
2025-09-03 22:30:09 -07:00
Mathias Agopian 639cdc3e5c add option to disable perfetto on android
The new cmake FILAMENT_ENABLE_PERFETTO must be set to enable 
perfetto traces on Android. It is disabled by default on release
builds, enabled otherwise.

The reason for this is that the perfetto SDK adds about 800K of code
to the library. The text section goes from 2.2 to 1.4 MB
2025-09-03 16:16:46 -07:00
Sungun Park b0f8e1be7a 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:05:34 +00:00
Ben Doherty 3bd6412780 Remove the setDebugTag API in favor of tagged create API (#9011) 2025-09-03 11:14:33 -04:00
Powei Feng 9fad497fa0 Enable c++20 for Android and iOS (#9150)
- Fix Android cmake files
- Change iOS samples to use c++20
2025-09-03 00:28:14 +00:00
Doris Wu ae5ebda397 Get actual backend type from the engine (#9171) 2025-09-02 22:27:35 +00:00
Ben Doherty 58dc6715c9 iOS: avoid use of typeof (#9173) 2025-09-02 19:24:22 +00:00
Mathias Agopian d3ff60af21 remove all uses of std::string in filament
- libbackend (except webgpu)
- libfilament
- libutils

std::string generates a lot of code bloat, we use CString instead.

We also update CString to be more compatible with std::string's api.
2025-09-02 11:47:58 -07:00
Filament Bot 1c2fe0ce39 [automated] Updating /docs due to commit f875dc2
Full commit hash is f875dc2c08

DOCS_ALLOW_DIRECT_EDITS
2025-09-02 18:33:11 +00:00
Powei Feng f875dc2c08 Release Filament 1.64.1 2025-09-02 11:17:37 -07:00
Powei Feng 19e1287392 Fix minor typo and styling issues (#9172) 2025-09-02 18:11:09 +00:00
Powei Feng 7d1a09773e vk: fix readpixels validation error (#9155)
The semaphore stages between command buffer didn't consider the
data buffers (UBOS, vertices, indices) being shared across command
buffers

BUG=436853814
2025-09-02 17:44:35 +00:00
Mathias Agopian 05a6198443 froxelization optimizations
- by limiting the maximum number of point light to 255 instead of 256,
  we can simplify some loops.

- hint the compiler that certain loop counters are multiple of 16 and 
non 0, which helps vectorizing.
2025-08-29 14:46:14 -07:00
Mathias Agopian 00bd30c21b zLightNear and zLightFar are now clamped
To avoid unexpected results, View::setDynamicLightingOptions() now
clamps the parameters between the camera's near and far plane.
2025-08-29 14:46:14 -07:00
Mathias Agopian 88fa99d782 The Record buffer is now dynamically sized.
The record buffer is were we store the light indices, its maximum
size is 65536 entries, but is often limited to 16384 on about 30%
of Android devices because of the 16KB UBO limit.

This PR makes the record buffer use up to 64K entries when allowed
but the h/w.

The record buffer can be a limiting factor when many lights are used
with many froxels. With the minimum of 4096 froxels and a 16KB record 
buffer we get an average of 4 lights per froxel. With our maximum of
8192 froxels and a 64KB record buffer we get 8 lights in average per
froxel.
2025-08-29 14:46:14 -07:00
Mathias Agopian b57fb8cc13 Missing includes and small cleanups 2025-08-29 14:46:14 -07:00
Mathias Agopian 9f3c0ec8ef Update all per-object/instance buffers all at once
FIXES=[433807402]
2025-08-29 14:45:36 -07:00
Mathias Agopian 6d0a47b37c add concept of offset to instancebuffer offset 2025-08-29 14:45:36 -07:00
Mathias Agopian 39bf0f0a71 move FScene::updateUBO() back to FView
it really didn't belong to FScene
2025-08-29 14:45:36 -07:00
Filament Bot a7894b5876 [automated] Updating /docs due to commit 44ed67b
Full commit hash is 44ed67bfb6

DOCS_ALLOW_DIRECT_EDITS
2025-08-29 21:22:42 +00:00
Powei Feng 44ed67bfb6 docs add performance analysis page 2025-08-29 14:19:28 -07:00
Andy Hovingh 1765f1421d additional performance analysis documentation, namely on locking GPU frequency 2025-08-29 14:26:44 -05:00
Juan Caldas 4a4c4b276f Remove temp gltf sample (#9166) 2025-08-29 18:50:26 +00:00
FireBanana 8c985607b8 Remove extra tab in PassNode 2025-08-29 11:04:13 -07:00
Juan Caldas 090941c35a webgpu: Remove temporary file (#9165) 2025-08-29 18:00:41 +00:00
Andy Hovingh 7e6d6f6635 webgpu: fix linux build with added unit tests 2025-08-29 12:39:35 -05:00
Juan Caldas a695170193 Add missing attributes to sample (#9160) 2025-08-29 12:52:12 +00:00
rafadevai eed71107c9 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 01:30:27 +00:00
Juan Caldas 74ba3eb00c webgpu: Support skinning on WebGPU (#9137)
BUGS = [436886048]
2025-08-29 00:24:14 +00:00
Powei Feng 088900e6e0 Fix bones indices and weights sampler + descriptor set (#9154)
In some places, this sampler was incorrectly assumed to be
sampler2darray, but it should be just a sampler2d.  Additionally,
sampling from it should produce unfiltered values - this has been
changed accordingly.
2025-08-28 14:05:16 -07:00
Syed Idris Shah 60ab596e39 wgpu: fix the deadlock in finish call for gltf_viewer
gltf_viewer on android calls finish before creating any resources.
This causes a hang on OnSubmittedWorkDone for the work that was never
there. Put a check in Driver::finish call to avoid the deadlock.
2025-08-28 14:42:44 -04:00
Sungun Park e03b077e9b 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-28 18:10:09 +00:00
Juan CaldasandAndy Hovingh f5418cb866 webgpu: Handle stacked swizzles (#9149)
BUGS = [433944896]

---------

Co-authored-by: Andy Hovingh <6198728+AndyHovingh@users.noreply.github.com>
2025-08-28 17:12:44 +00:00
Syed Idris Shah 9b75b18426 wgpu: Fix linux build
webgpu build on linux was broken because of 45fcea101f.
Resolve the symbols conflict between webgpu and X11.
2025-08-28 12:06:08 -04:00
Powei Feng 8f5f007e83 vk: fix rendertarget uninitialized fields (#9153) 2025-08-27 13:38:47 -07:00
Sungun Park 1aab0585da Disable amortized shader compile by default (#9151)
This is a temporary resolution until we fix an underlying issue.
2025-08-27 12:46:58 -07:00
Andy Hovingh 1d1e15d915 webgpu: profiling and system tracing support 2025-08-27 10:41:14 -05:00
Doris Wu ff394f7c1b feat: Add Visibility Bitmask method for GTAO (#9101)
* Quick test

* Fix incorrect logic and add some comments

* Set thickness parameter

* refactoring

* Update

* Generated files

* Some comments

* Update

* Update generated files

* Update

* Update

* Add comments
2025-08-26 23:27:02 +00:00
Syed Idris Shah 161b75b9b7 wgpu: Fix samples on linux
Window size should be calculated from windows not screen on XLIB.
XCB window is not implemented in Dawn. Remove the stale/wrong implementation in filament
2025-08-25 16:51:04 -04:00
Powei FengandSerge Metral bc12a56920 vk: check rebind flow if bindDescriptorSet called between draw2 (#9139)
In the case with external samplers, if another descriptor set gets
bound between draw2(), then we need to check to see if a rebinding
of the pipeline is necessary.

Co-authored-by: Serge Metral <sergemetral@google.com>
2025-08-25 09:04:11 -07:00
Mathias Agopian 15bb295ec6 A new froxel grid vizualization for FilamentApp
FilamentApp now has debugging options to enable or disable the
camera and directional shadow frustums, as well as the new
"froxel grid" visualization.

"froxel grid" is automatically enabled when "froxel debugging" is
enabled in the debug gui in gltf_viewer.


New corresponding debugging APIs were added to View.
2025-08-22 15:55:46 -07:00
Mathias Agopian cea178a40c froxel vizualization can now be turned on/off per view
Before this change once the froxel vizualizaition was enabled via
the Engine debug framework, it applied to all views. This adds a
debug API on View to control whether the view will display this
vizualization.
2025-08-22 15:55:46 -07:00
Mathias Agopian f34bb3d775 ViewerGui: hide stereo options when stereo is not enabled 2025-08-22 15:37:06 -07:00
Mathias Agopian 30112b5b5b gltf_Viewer: the -y (--eyes) options wasn't working 2025-08-22 15:37:06 -07:00
Mathias Agopian 9aaa1bf413 FilamentApp: fix projection matrix
For some reason we were not setting the aspect-ratio to 1 and scaling 
the clip-space instead. This could lead to lighting and clipping
issues.
2025-08-22 15:37:06 -07:00
Powei Feng 0471c5de2f vk: use firstBitSet API (#9128)
This is more efficient than the prevoius way
2025-08-22 22:31:48 +00:00
Juan Caldas 65cca71abf webGPU Run Load Image Tests (#9140) 2025-08-22 18:11:16 -04:00
Doris Wu e3384feee0 Clamp before assign to uint (#9132) (b/440220363) 2025-08-22 03:51:11 +00:00
Mathias Agopian 3650556de4 make sure PixelParams::thickness is initialized
If screen-space refraction was used enabled but the thickness
parameter wasn't explicitly set in the material, it would end-up
being uninitialized. Now it's initialized to 0.5 by default,
which is the value used for subsurface.

Also removed some calculations dependent on thickness being set, as
they assumed a thickness of 0.
2025-08-21 20:25:01 -07:00
Powei Feng 679b08b5db github: add script and action for getting gltf assets (#9085)
- Script for getting models from glTF-Sample-Assets
- Add support for reading gltf models from a file.
2025-08-21 22:16:12 +00:00
Juan Caldas 5fd5cd270c webgpu: Skip failing tests for WebGPU (#9133)
BUGS = [424157731]
2025-08-21 20:37:32 +00:00
Andy Hovingh 275ffb409f wgpu: add texture swizzle support (#9129)
BUGS = [433944896]
2025-08-21 20:03:37 +00:00
491 changed files with 17202 additions and 14701 deletions
+3 -1
View File
@@ -65,4 +65,6 @@ SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 4
UseTab: Never
PackConstructorInitializers: Never
PackConstructorInitializers: Never
ConstructorInitializerIndentWidth: 8
IndentWrappedFunctionNames: true
@@ -0,0 +1,23 @@
name: 'Get and cache glTF Assets'
description: 'Downloads and caches glTF assets by calling the get-gltf-sample-assets.sh script.'
runs:
using: "composite"
steps:
- uses: ./.github/actions/dep-versions
- name: Hash models file
id: hash-models
shell: bash
run: echo "hash=$(cat test/renderdiff/tests/gltf_models.txt | md5sum | sed 's/ -//g')" >> $GITHUB_OUTPUT
- name: Cache glTF assets
id: cache-gltf
uses: actions/cache@v4
with:
path: gltf
key: gltf-assets-${{ env.GITHUB_GLTF_SAMPLE_ASSETS_COMMIT }}-${{ steps.hash-models.outputs.hash }}
- name: Download assets via script if cache not found
if: steps.cache-gltf.outputs.cache-hit != 'true'
shell: bash
run: |
echo "Cache miss for commit ${{ env.GITHUB_GLTF_SAMPLE_ASSETS_COMMIT }}. Running download script..."
xargs bash build/common/get-gltf-sample-assets.sh < test/renderdiff/tests/gltf_models.txt
+3 -2
View File
@@ -1,5 +1,6 @@
name: 'Get Mesa'
description: 'Caches and installs Mesa'
name: 'Get and cache Mesa'
description: 'Get and cache Mesa'
runs:
using: "composite"
steps:
+4 -1
View File
@@ -8,7 +8,7 @@ runs:
uses: actions/cache@v3
id: cache-vulkan-sdk
with:
path: ${{ runner.homedir }}/VulkanSDK
path: ~/VulkanSDK
key: vulkansdk-${{ env.GITHUB_VULKANSDK_VERSION }}-2-${{ runner.os }}
- name: Download Vulkan SDK
if: steps.cache-vulkan-sdk.outputs.cache-hit != 'true'
@@ -21,6 +21,9 @@ runs:
run: |
source ${{ github.workspace }}/build/common/get-vulkan-sdk.sh
unpack_vulkan_installer
shell: bash
- name: Run Vulkan SDK setup
run: |
pushd .
cd ~/VulkanSDK/${GITHUB_VULKANSDK_VERSION}
sudo ./install_vulkan.py
+3 -1
View File
@@ -14,10 +14,12 @@ runs:
id: brew-cache
uses: actions/cache@v4 # Use a specific version
with:
path: $HOME/Library/Caches/Homebrew
path: ~/Library/Caches/Homebrew
key: ${{ runner.os }}-brew-20250424
- name: Install Mac Prerequisites
shell: bash
run: |
# Install brew prereqs
brew install coreutils
# Install ninja
source ./build/common/get-ninja.sh
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
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-32core'
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
+7 -5
View File
@@ -26,7 +26,7 @@ jobs:
build-desktop-linux:
name: build-linux
runs-on: ubuntu-22.04-16core
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
@@ -118,11 +118,12 @@ 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
- uses: ./.github/actions/mac-prereq
- uses: ./.github/actions/get-mesa
- uses: ./.github/actions/get-vulkan-sdk
- name: Prerequisites
run: |
pip install tifffile numpy
@@ -132,6 +133,7 @@ jobs:
- name: Render and compare
id: render_compare
run: |
ls ./gltf/Models
TEST_DIR=test/renderdiff
source ${TEST_DIR}/src/preamble.sh
start_
@@ -169,7 +171,7 @@ jobs:
validate-wgsl-webgpu:
name: validate-wgsl-webgpu
runs-on: 'ubuntu-24.04-8core'
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
+1 -1
View File
@@ -31,7 +31,7 @@ on:
jobs:
build-linux:
name: build-linux
runs-on: ubuntu-22.04-32core
runs-on: 'ubuntu-24.04-16core'
if: github.event_name == 'release' || github.event.inputs.platform == 'desktop'
steps:
+6
View File
@@ -18,3 +18,9 @@ test*.json
results
/compile_commands.json
/.cache
# For /test/renderdiff dependencies
/mesa
/gltf
/filament-assets
/venv
+1 -1
View File
@@ -391,7 +391,7 @@ Alternatively, if you have node installed you can use the
[live-server](https://www.npmjs.com/package/live-server) package, which automatically refreshes the
web page when it detects a change.
Each sample app has its own handwritten html file. Additionally the server folder contains assets
Each sample app has its own handwritten html file. Additionally, the server folder contains assets
such as meshes, textures, and materials.
## Running the native samples
+11 -2
View File
@@ -351,7 +351,7 @@ else()
endif()
if (FILAMENT_USE_EXTERNAL_GLES3)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_EXTERNAL_GLES3")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFILAMENT_USE_EXTERNAL_GLES3")
endif()
if (FILAMENT_SUPPORTS_EGL_ON_LINUX)
@@ -532,6 +532,15 @@ if (FILAMENT_SUPPORTS_OPENGL)
add_definitions(-DFILAMENT_SUPPORTS_OPENGL)
endif()
if (CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
option(FILAMENT_ENABLE_PERFETTO "Enable perfetto SDK on Android" OFF)
else()
option(FILAMENT_ENABLE_PERFETTO "Enable perfetto SDK on Android" ON)
endif()
if (FILAMENT_ENABLE_PERFETTO)
add_definitions(-DFILAMENT_ENABLE_PERFETTO)
endif()
# By default, build with Vulkan support on desktop platforms, although clients must request to use
# it at run time.
if (WIN32 OR WEBGL OR IOS)
@@ -633,7 +642,7 @@ endif()
# With WebGPU, Tint does not support ClipDistance which is used in Stereo. Mentioned in comment
# https://github.com/google/dawn/blob/855d17b08abdf02f9142bf5a8f14d0ea088810a4/src/tint/lang/spirv/reader/ast_parser/function.cc#L4434
if (FILAMENT_SUPPORTS_WEBGPU)
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a webgpu --variant-filter=skinning,stereo)
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a webgpu --variant-filter=stereo)
endif()
# Disable ESSL 1.0 code generation.
+18 -6
View File
@@ -20,7 +20,7 @@ The guiding principles of the filament code style and code formatting can be res
- class access modifiers are not indented
- last line of `.cpp` or `.h` file must be an empty line
```
```c++
for (int i = 0; i < max; i++) {
}
@@ -73,12 +73,24 @@ src/data.inc
- `public` class attributes *are not* prefixed
- class attributes and methods are lower camelcase
```
```c++
extern int gGlobalWarming;
class FooBar {
public:
void methodName();
FooBar(int attributeName, int sizeInBytes)
: mAttributeName(attributeName),
sizeInBytes(sizeInBytes) {}
void reallyLongMethodNameWithLotsOfArguments(bool argument1,
int someSecondArgument, int bestArgument) {
std::pair<bool, int> pair = {
argument1,
argument2,
};
// etc
}
int sizeInBytes;
private:
int mAttributeName;
@@ -97,7 +109,7 @@ private:
- always include the copyright notice at the top of every file
- make sure the date is correct
```
```c++
/*
* Copyright (C) 2018 The Android Open Source Project
*
@@ -139,7 +151,7 @@ conversely containers and algorithms are not allowed. There are exceptions such
*Sorting the headers is important to help catching missing `#include` directives.*
```
```c++
/*
* Copyright (C) 2018 The Android Open Source Project
*
@@ -183,7 +195,7 @@ conversely containers and algorithms are not allowed. There are exceptions such
### Misc
- Use `auto` only when the type appears on the same line or with iterators and lambdas.
```
```c++
auto foo = new Foo();
for (auto& i : collection) { }
```
-1
View File
@@ -1,7 +1,6 @@
# Filament Release Notes log
**If you are merging a PR into main**: please add the release note below, under the *Release notes
We are chaning the way Vulkan buffers are handled. We need to switch over to a managed (or view-based) model where the data stored inside the object is a proxy to a Vulkan object that can dynamically be swapped around.
**If you are cherry-picking a commit into an rc/ branch**: add the release note under the
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
+2 -2
View File
@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.64.1'
implementation 'com.google.android.filament:filament-android:1.66.0'
}
```
@@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
iOS projects can use CocoaPods to install the latest release:
```shell
pod 'Filament', '~> 1.64.1'
pod 'Filament', '~> 1.66.0'
```
## Documentation
+31
View File
@@ -7,6 +7,37 @@ 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.66.1
- filamat: Removed a dependency on Glslang's deprecated SPIR-V remapper.
The functionality is already implemented by calling the CanonicalizeIds pass
in the SPIRV-Tools, and should be a non-functional change.
## v1.66.0
- materials: include default values of spec constants in material metadata [⚠️ **Recompile Materials**]
## v1.65.4
## v1.65.3
## v1.65.2
## v1.65.1
- `setFrameScheduledCallback` now works on all backends (frame presentation scheduling is still only
available on Metal). Non-Metal backends can use the callback to be notified when Filament has
finished processing a frame on the CPU.
- materials: added `getEyeFromViewMatrix()` for vertex shader [⚠️ **Recompile Materials**]
- matc: make `--workarounds=none` the default [**Recompile Materials to take effect**]
## v1.65.0
lighting: the intermediate froxel record buffer is now dynamically sized [⚠️ **New Material Version**]
## v1.64.1
- Update CMake minimum version to 3.22.1
+2
View File
@@ -178,6 +178,8 @@ nexusPublishing {
repositories {
sonatype {
stagingProfileId = '9a75a224a4f17b'
nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/"))
snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/"))
}
}
}
@@ -146,7 +146,7 @@ abstract class MaterialCompiler extends TaskWithBinary {
.gradleProperty("com.google.android.filament.include-webgpu")
.forUseAtConfigurationTime().present
if (include_webgpu) {
matcArgs += ['-a', 'webgpu', '--variant-filter=skinning,stereo']
matcArgs += ['-a', 'webgpu', '--variant-filter=stereo']
}
def mat_no_opt = providers
+2
View File
@@ -1,6 +1,8 @@
cmake_minimum_required(VERSION 3.19)
project(filamat-android)
set(CMAKE_CXX_STANDARD 20)
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
+19 -17
View File
@@ -7,6 +7,8 @@ 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)
set(CMAKE_CXX_STANDARD 20)
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
add_library(filament STATIC IMPORTED)
@@ -130,6 +132,14 @@ add_library(filament-jni SHARED
../common/NioUtils.cpp
)
target_include_directories(filament-jni PRIVATE
..
${FILAMENT_DIR}/include
../../filament/backend/include
../../third_party/robin-map
../../third_party/perfetto
../../libs/utils/include)
# Ordering is significant in the following list. The PRIVATE qualifier prevents transitive deps.
target_link_libraries(filament-jni
PRIVATE filament-generatePrefilterMipmap
@@ -144,29 +154,21 @@ target_link_libraries(filament-jni
PRIVATE android
PRIVATE jnigraphics
PRIVATE utils
PRIVATE perfetto
PRIVATE abseil
PRIVATE perfetto # needed only when FILAMENT_ENABLE_PERFETTO is defined
PRIVATE abseil # needed only when FILAMENT_USE_ABSEIL_LOGGING is defined
PRIVATE zstd
# libgeometry is PUBLIC because gltfio uses it.
PUBLIC geometry
$<$<STREQUAL:${FILAMENT_ENABLE_FGVIEWER},ON>:fgviewer>
$<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:matdbg>
$<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:filamat>
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:bluevk>
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:vkshaders>
$<$<STREQUAL:${FILAMENT_SUPPORTS_WEBGPU},ON>:webgpu_dawn>
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:smol-v>
PRIVATE $<$<STREQUAL:${FILAMENT_ENABLE_FGVIEWER},ON>:fgviewer>
PRIVATE $<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:matdbg>
PRIVATE $<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:filamat>
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:bluevk>
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:vkshaders>
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:smol-v>
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_WEBGPU},ON>:webgpu_dawn>
)
target_include_directories(filament-jni PRIVATE
..
${FILAMENT_DIR}/include
../../filament/backend/include
../../third_party/robin-map
../../third_party/perfetto
../../libs/utils/include)
# Force a relink when the version script is changed:
set_target_properties(filament-jni PROPERTIES LINK_DEPENDS ${VERSION_SCRIPT})
@@ -450,6 +450,13 @@ Java_com_google_android_filament_RenderableManager_nGetPrimitiveCount(JNIEnv*, j
return (jint) rm->getPrimitiveCount((RenderableManager::Instance) i);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_RenderableManager_nGetInstanceCount(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
return (jint) rm->getInstanceCount((RenderableManager::Instance) i);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetMaterialInstanceAt(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jint primitiveIndex, jlong nativeMaterialInstance) {
@@ -208,3 +208,19 @@ Java_com_google_android_filament_Renderer_nSetVsyncTime(JNIEnv *, jclass,
Renderer *renderer = (Renderer *) nativeRenderer;
renderer->setVsyncTime(steadyClockTimeNano);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_Renderer_nSkipNextFrames(JNIEnv *, jclass ,
jlong nativeRenderer, jint frameCount) {
Renderer *renderer = (Renderer *) nativeRenderer;
renderer->skipNextFrames(frameCount);
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_google_android_filament_Renderer_nGetFrameToSkipCount(JNIEnv *, jclass ,
jlong nativeRenderer) {
Renderer *renderer = (Renderer *) nativeRenderer;
return renderer->getFrameToSkipCount();
}
@@ -28,9 +28,8 @@ Java_com_google_android_filament_SwapChain_nSetFrameCompletedCallback(JNIEnv* en
jlong nativeSwapChain, jobject handler, jobject runnable) {
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
auto* callback = JniCallback::make(env, handler, runnable);
swapChain->setFrameCompletedCallback(nullptr, [callback](SwapChain* swapChain) {
JniCallback::postToJavaAndDestroy(callback);
});
swapChain->setFrameCompletedCallback(callback->getHandler(),
[callback](SwapChain* swapChain) { JniCallback::postToJavaAndDestroy(callback); });
}
extern "C" JNIEXPORT jboolean JNICALL
@@ -40,9 +39,35 @@ Java_com_google_android_filament_SwapChain_nIsSRGBSwapChainSupported(
return (jboolean)SwapChain::isSRGBSwapChainSupported(*engine);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_SwapChain_nIsMSAASwapChainSupported(
JNIEnv *, jclass, jlong nativeEngine, jint samples) {
Engine* engine = (Engine*) nativeEngine;
return (jboolean)SwapChain::isMSAASwapChainSupported(*engine, samples);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_SwapChain_nIsProtectedContentSupported(
JNIEnv *, jclass, jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jboolean)SwapChain::isProtectedContentSupported(*engine);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_SwapChain_nSetFrameScheduledCallback(JNIEnv* env, jclass,
jlong nativeSwapChain, jobject handler, jobject runnable) {
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
auto* callback = JniCallback::make(env, handler, runnable);
swapChain->setFrameScheduledCallback(callback->getHandler(),
[callback](backend::PresentCallable) {
// Ignore PresentCallable, which is only meaningful with the Metal backend.
JniCallback::postToJavaAndDestroy(callback);
});
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_SwapChain_nIsFrameScheduledCallbackSet(
JNIEnv *, jclass, jlong nativeSwapChain) {
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
return (jboolean)swapChain->isFrameScheduledCallbackSet();
}
@@ -356,6 +356,7 @@ Java_com_google_android_filament_View_nSetFogOptions(JNIEnv *, jclass , jlong na
view->setFogOptions(options);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetBlendMode(JNIEnv *, jclass , jlong nativeView, jint blendMode) {
View* view = (View*) nativeView;
@@ -554,3 +555,20 @@ Java_com_google_android_filament_View_nClearFrameHistory(JNIEnv *env, jclass cla
Engine *engine = (Engine *) nativeEngine;
view->clearFrameHistory(*engine);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetChannelDepthClearEnabled(JNIEnv *, jclass ,
jlong nativeView, jint channel, jboolean enabled) {
View* view = (View*) nativeView;
view->setChannelDepthClearEnabled((uint8_t) channel, (bool) enabled);
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_View_nIsChannelDepthClearEnabled(JNIEnv *env, jclass clazz,
jlong nativeView, jint channel) {
// TODO: implement nIsChannelDepthClearEnabled()
View* view = (View*) nativeView;
return (jboolean)view->isChannelDepthClearEnabled((uint8_t) channel);
}
@@ -332,7 +332,7 @@ public class RenderableManager {
}
/**
* Set the channel this renderable is associated to. There can be 4 channels.
* Set the channel this renderable is associated to. There can be 8 channels.
*
* <p>All renderables in a given channel are rendered together, regardless of anything else.
* They are sorted as usual within a channel.</p>
@@ -342,7 +342,7 @@ public class RenderableManager {
* <p>Channels 0 and 1 may not have render primitives using a material with `refractionType`
* set to `screenspace`.</p>
*
* @param channel clamped to the range [0..3], defaults to 2.
* @param channel clamped to the range [0..7], defaults to 2.
*
* @return Builder reference for chaining calls.
*
@@ -351,7 +351,7 @@ public class RenderableManager {
* @see RenderableManager::setBlendOrderAt()
*/
@NonNull
public Builder channel(@IntRange(from = 0, to = 3) int channel) {
public Builder channel(@IntRange(from = 0, to = 7) int channel) {
nBuilderChannel(mNativeBuilder, channel);
return this;
}
@@ -730,7 +730,7 @@ public class RenderableManager {
*
* @see Builder#channel
*/
public void setChannel(@EntityInstance int i, @IntRange(from = 0, to = 3) int channel) {
public void setChannel(@EntityInstance int i, @IntRange(from = 0, to = 7) int channel) {
nSetChannel(mNativeObject, i, channel);
}
@@ -851,6 +851,14 @@ public class RenderableManager {
return nGetPrimitiveCount(mNativeObject, i);
}
/**
* Gets the immutable number of instances in the given renderable.
*/
@IntRange(from = 0)
public int getInstanceCount(@EntityInstance int i) {
return nGetInstanceCount(mNativeObject, i);
}
/**
* Changes the material instance binding for the given primitive.
*
@@ -1018,6 +1026,7 @@ public class RenderableManager {
private static native boolean nIsShadowReceiver(long nativeRenderableManager, int i);
private static native void nGetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float[] center, float[] halfExtent);
private static native int nGetPrimitiveCount(long nativeRenderableManager, int i);
private static native int nGetInstanceCount(long nativeRenderableManager, int i);
private static native void nSetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex, long nativeMaterialInstance);
private static native void nClearMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex);
private static native long nGetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex);
@@ -732,6 +732,22 @@ public class Renderer {
nResetUserTime(getNativeObject());
}
/**
* Requests the next frameCount frames to be skipped. For Debugging.
* @param frameCount number of frames to skip.
*/
public void skipNextFrames(int frameCount) {
nSkipNextFrames(getNativeObject(), frameCount);
}
/**
* Remainder count of frame to be skipped
* @return remaining frames to be skipped
*/
public int getFrameToSkipCount() {
return nGetFrameToSkipCount(getNativeObject());
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed Renderer");
@@ -773,4 +789,7 @@ public class Renderer {
float interval, float headRoomRatio, float scaleRate, int history);
private static native void nSetClearOptions(long nativeRenderer,
float r, float g, float b, float a, boolean clear, boolean discard);
private static native void nSkipNextFrames(long nativeObject, int frameCount);
private static native int nGetFrameToSkipCount(long nativeObject);
}
@@ -97,6 +97,19 @@ public class SwapChain {
return nIsSRGBSwapChainSupported(engine.getNativeObject());
}
/**
* Return whether createSwapChain supports the CONFIG_MSAA_*_SAMPLES flag.
* The default implementation returns false.
*
* @param engine A reference to the filament Engine
* @param samples The number of samples
* @return true if CONFIG_MSAA_*_SAMPLES is supported, false otherwise.
* @see SwapChainFlags#CONFIG_MSAA_*_SAMPLES
*/
public static boolean isMSAASwapChainSupported(@NonNull Engine engine, int samples) {
return nIsMSAASwapChainSupported(engine.getNativeObject(), samples);
}
/**
* @return the native <code>Object</code> this <code>SwapChain</code> was created from or null
* for a headless SwapChain.
@@ -126,6 +139,78 @@ public class SwapChain {
nSetFrameCompletedCallback(getNativeObject(), handler, callback);
}
/**
* FrameScheduledCallback is a callback function that notifies an application about the status
* of a frame after Filament has finished its processing.
*
* <p>
* The exact timing and semantics of this callback differ depending on the graphics backend in
* use.
* </p>
*
* <h3>Metal Backend</h3>
* <p>
* With the Metal backend, this callback signifies that Filament has completed all CPU-side
* processing for a frame and the frame is ready to be scheduled for presentation.
* </p>
*
* <p>
* Typically, Filament is responsible for scheduling the frame's presentation to the SwapChain.
* If a FrameScheduledCallback is set, however, the application bears the responsibility of
* scheduling the frame for presentation by calling the PresentCallable passed to the callback
* function. In this mode, Filament will not automatically schedule the frame for presentation.
* </p>
*
* <p>
* When using the Metal backend, if your application delays the call to the PresentCallable
* (e.g., by invoking it on a separate thread), you must ensure all PresentCallables have been
* called before shutting down the Filament Engine. You can guarantee this by calling
* Engine.flushAndWait() before Engine.shutdown(). This is necessary to ensure the Engine has
* a chance to clean up all memory related to frame presentation.
* </p>
*
* <h3>Other Backends (OpenGL, Vulkan, WebGPU)</h3>
* <p>
* On other backends, this callback serves as a notification that Filament has completed all
* CPU-side processing for a frame. Filament proceeds with its normal presentation logic
* automatically, and the PresentCallable passed to the callback is a no-op that can be safely
* ignored.
* </p>
*
* <h3>General Behavior</h3>
* <p>
* A FrameScheduledCallback can be set on an individual SwapChain through
* setFrameScheduledCallback. Each SwapChain can have only one callback set per frame. If
* setFrameScheduledCallback is called multiple times on the same SwapChain before
* Renderer.endFrame(), the most recent call effectively overwrites any previously set callback.
* </p>
*
* <p>
* The callback set by setFrameScheduledCallback is "latched" when Renderer.endFrame() is
* executed. At this point, the callback is fixed for the frame that was just encoded.
* Subsequent calls to setFrameScheduledCallback after endFrame() will apply to the next frame.
* </p>
*
* <p>
* Use setFrameScheduledCallback() (with default arguments) to unset the callback.
* </p>
*
* @param handler A {@link java.util.concurrent.Executor Executor}.
* @param callback The Runnable callback to invoke when frame processing is complete.
*/
public void setFrameScheduledCallback(@NonNull Object handler, @NonNull Runnable callback) {
nSetFrameScheduledCallback(getNativeObject(), handler, callback);
}
/**
* Returns whether this SwapChain currently has a FrameScheduledCallback set.
*
* @return true, if the last call to setFrameScheduledCallback set a callback
*/
public boolean isFrameScheduledCallbackSet() {
return nIsFrameScheduledCallbackSet(getNativeObject());
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed SwapChain");
@@ -138,6 +223,9 @@ public class SwapChain {
}
private static native void nSetFrameCompletedCallback(long nativeSwapChain, Object handler, Runnable callback);
private static native void nSetFrameScheduledCallback(long nativeSwapChain, Object handler, Runnable callback);
private static native boolean nIsFrameScheduledCallbackSet(long nativeSwapChain);
private static native boolean nIsSRGBSwapChainSupported(long nativeEngine);
private static native boolean nIsMSAASwapChainSupported(long nativeEngine, int samples);
private static native boolean nIsProtectedContentSupported(long nativeEngine);
}
@@ -92,6 +92,15 @@ public final class SwapChainFlags {
* The SwapChain contains protected content. Only supported when isProtectedContentSupported()
* is true.
*/
public static final long CONFIG_PROTECTED_CONTENT = 0x40;
}
public static final long CONFIG_PROTECTED_CONTENT = 0x40;
/**
* Indicates that the SwapChain is configured to use Multi-Sample Anti-Aliasing (MSAA) with the
* given sample points within each pixel. Only supported when isMSAASwapChainSupported(4) is
* true.
*
* This is only supported by EGL(Android). Other GL platforms (GLX, WGL, etc) don't support it
* because the swapchain MSAA settings must be configured before window creation.
*/
public static final long CONFIG_MSAA_4_SAMPLES = 0x80;
}
@@ -231,7 +231,7 @@ public class View {
*
* <p>
* The View does not take ownership of the Scene pointer. Before destroying a Camera, be sure
* to remove it from all assoicated Views.
* to remove it from all associated Views. If the camera isn't set, Renderer::render() will result in a no-op.
* </p>
*
* @see #getCamera
@@ -291,6 +291,25 @@ public class View {
return mViewport;
}
/**
* Sets whether a channel must clear the depth buffer before all primitives are rendered.
* Channel depth clear is off by default for all channels.
* This is orthogonal to Renderer::setClearOptions().
* @param channel between 0 and 7
* @param enabled true to enable clear, false to disable
*/
void setChannelDepthClearEnabled(@IntRange(from = 0, to = 7) int channel, boolean enabled) {
nSetChannelDepthClearEnabled(getNativeObject(), channel, enabled);
}
/**
* @param channel between 0 and 7
* @return true if this channel has depth clear enabled.
*/
boolean isChannelDepthClearEnabled(@IntRange(from = 0, to = 7) int channel) {
return nIsChannelDepthClearEnabled(getNativeObject(), channel);
}
/**
* Sets the blending mode used to draw the view into the SwapChain.
*
@@ -1318,6 +1337,8 @@ public class View {
boolean lensFlare, boolean starburst, float chromaticAberration, int ghostCount, float ghostSpacing, float ghostThreshold, float haloThickness, float haloRadius, float haloThreshold);
private static native void nSetFogOptions(long nativeView, float distance, float maximumOpacity, float height, float heightFalloff, float cutOffDistance, float v, float v1, float v2, float density, float inScatteringStart, float inScatteringSize, boolean fogColorFromIbl, long skyColorNativeObject, boolean enabled);
private static native void nSetStereoscopicOptions(long nativeView, boolean enabled);
private static native void nSetChannelDepthClearEnabled(long nativeView, int channel, boolean enabled);
private static native boolean nIsChannelDepthClearEnabled(long nativeView, int channel);
private static native void nSetBlendMode(long nativeView, int blendMode);
private static native void nSetDepthOfFieldOptions(long nativeView, float cocScale, float maxApertureDiameter, boolean enabled, int filter,
boolean nativeResolution, int foregroundRingCount, int backgroundRingCount, int fastGatherRingCount, int maxForegroundCOC, int maxBackgroundCOC);
@@ -1615,7 +1636,7 @@ public class View {
*
* This value is used as a tint instead, when fogColorFromIbl is enabled.
*
* @see fogColorFromIbl
* @see #fogColorFromIbl
*/
@NonNull @Size(min = 3)
public float[] color = {1.0f, 1.0f, 1.0f};
@@ -1656,7 +1677,7 @@ public class View {
*
* `fogColorFromIbl` is ignored when skyTexture is specified.
*
* @see skyColor
* @see #skyColor
*/
public boolean fogColorFromIbl = false;
/**
@@ -1674,7 +1695,7 @@ public class View {
* In `linearFog` mode mipmap level 0 is always used.
*
* @see Texture
* @see fogColorFromIbl
* @see #fogColorFromIbl
*/
@Nullable
public Texture skyColor = null;
@@ -1796,7 +1817,8 @@ public class View {
/**
* Structure used to set the precision of the color buffer and related quality settings.
*
* @see setRenderQuality, getRenderQuality
* @see #setRenderQuality
* @see #getRenderQuality
*/
public static class RenderQuality {
/**
@@ -1814,7 +1836,7 @@ public class View {
/**
* Options for screen space Ambient Occlusion (SSAO) and Screen Space Cone Tracing (SSCT)
* @see setAmbientOcclusionOptions()
* @see #setAmbientOcclusionOptions
*/
public static class AmbientOcclusionOptions {
public enum AmbientOcclusionType {
@@ -1949,12 +1971,24 @@ public class View {
* Ground Truth-base Ambient Occlusion (GTAO) options
*/
public float gtaoThicknessHeuristic = 0.004f;
/**
* Ground Truth-base Ambient Occlusion (GTAO) options
*/
public boolean gtaoUseVisibilityBitmasks = false;
/**
* Ground Truth-base Ambient Occlusion (GTAO) options
*/
public float gtaoConstThickness = 0.5f;
/**
* Ground Truth-base Ambient Occlusion (GTAO) options
*/
public boolean gtaoLinearThickness = false;
}
/**
* Options for Multi-Sample Anti-aliasing (MSAA)
* @see setMultiSampleAntiAliasingOptions()
* @see #setMultiSampleAntiAliasingOptions
*/
public static class MultiSampleAntiAliasingOptions {
/**
@@ -1984,7 +2018,7 @@ public class View {
* `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.
*
* @see setTemporalAntiAliasingOptions()
* @see #setTemporalAntiAliasingOptions
*/
public static class TemporalAntiAliasingOptions {
public enum BoxType {
@@ -2086,7 +2120,7 @@ public class View {
/**
* Options for Screen-space Reflections.
* @see setScreenSpaceReflectionsOptions()
* @see #setScreenSpaceReflectionsOptions
*/
public static class ScreenSpaceReflectionsOptions {
/**
@@ -2120,7 +2154,9 @@ public class View {
/**
* List of available post-processing anti-aliasing techniques.
* @see setAntiAliasing, getAntiAliasing, setSampleCount
* @see #setAntiAliasing
* @see #getAntiAliasing
* @see #setSampleCount
*/
public enum AntiAliasing {
/**
@@ -2149,7 +2185,7 @@ public class View {
/**
* List of available shadow mapping techniques.
* @see setShadowType
* @see #setShadowType
*/
public enum ShadowType {
/**
@@ -2173,7 +2209,7 @@ public class View {
/**
* View-level options for VSM Shadowing.
* @see setVsmShadowOptions()
* @see #setVsmShadowOptions
* @warning This API is still experimental and subject to change.
*/
public static class VsmShadowOptions {
@@ -2214,7 +2250,7 @@ public class View {
/**
* View-level options for DPCF and PCSS Shadowing.
* @see setSoftShadowOptions()
* @see #setSoftShadowOptions
* @warning This API is still experimental and subject to change.
*/
public static class SoftShadowOptions {
+31 -11
View File
@@ -1,6 +1,14 @@
cmake_minimum_required(VERSION 3.19)
project(filament-utils-android)
option(FILAMENT_SUPPORTS_VULKAN "Enables Vulkan on Android" OFF)
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)
set(CMAKE_CXX_STANDARD 20)
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
set(IMAGEIO_DIR ../../libs/imageio)
@@ -30,7 +38,16 @@ add_library(iblprefilter STATIC IMPORTED)
set_target_properties(iblprefilter PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilament-iblprefilter.a)
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libfilament-utils-jni.map")
add_library(utils STATIC IMPORTED)
set_target_properties(utils PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libutils.a)
add_library(perfetto STATIC IMPORTED)
set_target_properties(perfetto PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libperfetto.a)
set(VERSION_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/libfilament-utils-jni.map")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${VERSION_SCRIPT}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
add_library(filament-utils-jni SHARED
@@ -53,22 +70,25 @@ add_library(filament-utils-jni SHARED
target_compile_definitions(filament-utils-jni PUBLIC IMAGEIO_LITE=1)
target_include_directories(filament-utils-jni PRIVATE
${FILAMENT_DIR}/include
..
${FILAMENT_DIR}/include
../../filament/backend/include
${IMAGEIO_DIR}/include
../../libs/utils/include)
set_target_properties(filament-utils-jni PROPERTIES LINK_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/libfilament-utils-jni.symbols)
set_target_properties(filament-utils-jni PROPERTIES LINK_DEPENDS ${VERSION_SCRIPT})
# The ordering in the following list is important because CMake does not have dependency information.
target_link_libraries(filament-utils-jni
gltfio-jni
civetweb
camutils
iblprefilter
image
ktxreader
viewer
PRIVATE gltfio-jni
PRIVATE civetweb
PRIVATE camutils
PRIVATE iblprefilter
PRIVATE image
PRIVATE filament-jni
PRIVATE ktxreader
PRIVATE viewer
PRIVATE log
PRIVATE utils
PRIVATE perfetto # needed only when FILAMENT_ENABLE_PERFETTO is defined
)
+37 -69
View File
@@ -1,20 +1,27 @@
cmake_minimum_required(VERSION 3.19)
project(gltfio-android)
option(FILAMENT_SUPPORTS_VULKAN "Enables Vulkan on Android" OFF)
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)
set(CMAKE_CXX_STANDARD 20)
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
set(GLTFIO_DIR ../../libs/gltfio)
set(DRACO_DIR ../../third_party/draco)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../filament-android ${CMAKE_CURRENT_BINARY_DIR}/filament-android)
add_library(gltfio_core STATIC IMPORTED)
set_target_properties(gltfio_core PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgltfio_core.a)
add_library(dracodec STATIC IMPORTED)
set_target_properties(dracodec PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libdracodec.a)
add_library(meshoptimizer STATIC IMPORTED)
set_target_properties(meshoptimizer PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libmeshoptimizer.a)
add_library(ktxreader STATIC IMPORTED)
set_target_properties(ktxreader PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libktxreader.a)
@@ -27,10 +34,6 @@ add_library(basis_transcoder STATIC IMPORTED)
set_target_properties(basis_transcoder PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbasis_transcoder.a)
add_library(zstd STATIC IMPORTED)
set_target_properties(zstd PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libzstd.a)
add_library(utils STATIC IMPORTED)
set_target_properties(utils PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libutils.a)
@@ -47,60 +50,11 @@ add_library(uberarchive STATIC IMPORTED)
set_target_properties(uberarchive PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libuberarchive.a)
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.map")
set(VERSION_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.map")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${VERSION_SCRIPT}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
set(GLTFIO_SRCS
${GLTFIO_DIR}/include/gltfio/Animator.h
${GLTFIO_DIR}/include/gltfio/AssetLoader.h
${GLTFIO_DIR}/include/gltfio/FilamentAsset.h
${GLTFIO_DIR}/include/gltfio/FilamentInstance.h
${GLTFIO_DIR}/include/gltfio/MaterialProvider.h
${GLTFIO_DIR}/include/gltfio/NodeManager.h
${GLTFIO_DIR}/include/gltfio/TrsTransformManager.h
${GLTFIO_DIR}/include/gltfio/ResourceLoader.h
${GLTFIO_DIR}/include/gltfio/TextureProvider.h
${GLTFIO_DIR}/include/gltfio/math.h
${GLTFIO_DIR}/src/ArchiveCache.cpp
${GLTFIO_DIR}/src/ArchiveCache.h
${GLTFIO_DIR}/src/Animator.cpp
${GLTFIO_DIR}/src/AssetLoader.cpp
${GLTFIO_DIR}/src/DependencyGraph.cpp
${GLTFIO_DIR}/src/DependencyGraph.h
${GLTFIO_DIR}/src/DracoCache.cpp
${GLTFIO_DIR}/src/DracoCache.h
${GLTFIO_DIR}/src/FFilamentAsset.h
${GLTFIO_DIR}/src/FFilamentInstance.h
${GLTFIO_DIR}/src/FilamentAsset.cpp
${GLTFIO_DIR}/src/FilamentInstance.cpp
${GLTFIO_DIR}/src/FNodeManager.h
${GLTFIO_DIR}/src/FTrsTransformManager.h
${GLTFIO_DIR}/src/GltfEnums.h
${GLTFIO_DIR}/src/Ktx2Provider.cpp
${GLTFIO_DIR}/src/MaterialProvider.cpp
${GLTFIO_DIR}/src/NodeManager.cpp
${GLTFIO_DIR}/src/TrsTransformManager.cpp
${GLTFIO_DIR}/src/ResourceLoader.cpp
${GLTFIO_DIR}/src/StbProvider.cpp
${GLTFIO_DIR}/src/TangentsJob.cpp
${GLTFIO_DIR}/src/TangentsJob.h
${GLTFIO_DIR}/src/UbershaderProvider.cpp
${GLTFIO_DIR}/src/Utility.cpp
${GLTFIO_DIR}/src/Utility.h
${GLTFIO_DIR}/src/Wireframe.cpp
${GLTFIO_DIR}/src/Wireframe.h
${GLTFIO_DIR}/src/downcast.h
${GLTFIO_DIR}/src/extended/AssetLoaderExtended.cpp
${GLTFIO_DIR}/src/extended/AssetLoaderExtended.h
${GLTFIO_DIR}/src/extended/ResourceLoaderExtended.cpp
${GLTFIO_DIR}/src/extended/ResourceLoaderExtended.h
${GLTFIO_DIR}/src/extended/TangentsJobExtended.cpp
${GLTFIO_DIR}/src/extended/TangentsJobExtended.h
${GLTFIO_DIR}/src/extended/TangentSpaceMeshWrapper.cpp
${GLTFIO_DIR}/src/extended/TangentSpaceMeshWrapper.h
src/main/cpp/Animator.cpp
src/main/cpp/AssetLoader.cpp
src/main/cpp/FilamentAsset.cpp
@@ -118,24 +72,38 @@ set(GLTFIO_SRCS
set(GLTFIO_INCLUDE_DIRS
..
${FILAMENT_DIR}/include
../../filament/backend/include
${FILAMENT_DIR}/backend/include
../../libs/gltfio/include
../../third_party/zstd/lib
../../third_party/cgltf
../../third_party/meshoptimizer/src
../../third_party/robin-map
../../third_party/stb
../../third_party/perfetto
../../libs/utils/include
../../libs/ktxreader/include
)
add_library(gltfio-jni SHARED ${GLTFIO_SRCS})
target_include_directories(gltfio-jni PRIVATE ${GLTFIO_INCLUDE_DIRS})
set_target_properties(gltfio-jni PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.symbols)
set_target_properties(gltfio-jni PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.map)
target_link_libraries(gltfio-jni filament-jni utils perfetto uberzlib log stb ktxreader basis_transcoder zstd uberarchive)
target_link_libraries(gltfio-jni dracodec meshoptimizer)
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_DRACO_SUPPORTED=1)
target_include_directories(gltfio-jni PRIVATE ${GLTFIO_INCLUDE_DIRS})
target_include_directories(gltfio-jni PRIVATE ${DRACO_DIR}/src)
target_include_directories(gltfio-jni PRIVATE ${DRACO_DIR}/tnt)
# Force a relink when the version script is changed:
set_target_properties(gltfio-jni PROPERTIES LINK_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.symbols;${VERSION_SCRIPT}")
# The ordering in the following list is important because CMake does not have dependency information.
target_link_libraries(gltfio-jni
PRIVATE gltfio_core
PRIVATE ktxreader
PUBLIC filament-jni
PRIVATE stb
PRIVATE basis_transcoder
PRIVATE uberarchive
PRIVATE dracodec
PRIVATE utils
PRIVATE uberzlib
PRIVATE perfetto # needed only when FILAMENT_ENABLE_PERFETTO is defined
PRIVATE log # needed only when perfetto above is used
)
+1 -1
View File
@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.64.1
VERSION_NAME=1.66.0
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
@@ -24,7 +24,7 @@ android {
compileSdkVersion versions.compileSdk
defaultConfig {
applicationId "com.google.android.filament.hellocamera"
applicationId "com.google.android.filament.hellocam"
minSdkVersion 23
targetSdkVersion versions.targetSdk
}
+8 -1
View File
@@ -75,6 +75,8 @@ function print_help {
echo " -S type"
echo " Enable stereoscopic rendering where type is one of [instanced|multiview]. This is only"
echo " meant for building the samples."
echo " -P"
echo " Enable perfetto traces on Android. Disabled by default on the Release build, enabled otherwise."
echo ""
echo "Build types:"
echo " release"
@@ -204,6 +206,7 @@ MATOPT_GRADLE_OPTION=""
ASAN_UBSAN_OPTION=""
COVERAGE_OPTION=""
ENABLE_PERFETTO=""
BACKEND_DEBUG_FLAG_OPTION=""
@@ -413,6 +416,7 @@ function build_android_target {
${WEBGPU_OPTION} \
${BACKEND_DEBUG_FLAG_OPTION} \
${STEREOSCOPIC_OPTION} \
${ENABLE_PERFETTO} \
../..
ln -sf "out/cmake-android-${lc_target}-${arch}/compile_commands.json" \
../../compile_commands.json
@@ -806,7 +810,7 @@ function check_debug_release_build {
pushd "$(dirname "$0")" > /dev/null
while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:" opt; do
while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:P" opt; do
case ${opt} in
h)
print_help
@@ -954,6 +958,9 @@ while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:" opt; do
V) COVERAGE_OPTION="-DFILAMENT_ENABLE_COVERAGE=ON"
echo "Enabled coverage"
;;
P) ENABLE_PERFETTO="-DFILAMENT_ENABLE_PERFETTO=ON"
echo "Enabled perfetto"
;;
x) BACKEND_DEBUG_FLAG_OPTION="-DFILAMENT_BACKEND_DEBUG_FLAG=${OPTARG}"
;;
S) case $(echo "${OPTARG}" | tr '[:upper:]' '[:lower:]') in
@@ -0,0 +1,349 @@
#!/usr/bin/env python3
# Copyright (C) 2025 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.
"""
This script automates the process of closing a Sonatype OSSRH staging repository.
To run the script:
python3 ./close-sonatype-staging-repository.py
To run the embedded unit tests:
python3 ./close-sonatype-staging-repository.py test
"""
import sys
import os
import base64
import json
import pathlib
import unittest
import io
from unittest import mock
import urllib.request
import urllib.error
PROPERTIES_PATH = pathlib.Path.home() / ".gradle" / "gradle.properties"
API_BASE_URL = "https://ossrh-staging-api.central.sonatype.com/manual"
def get_gradle_credentials(file_path: pathlib.Path) -> (str, str):
"""
Reads sonatypeUsername and sonatypePassword from the properties file.
"""
if not file_path.exists():
print(f"Error: Properties file not found at {file_path}", file=sys.stderr)
sys.exit(1)
username = None
password = None
try:
with open(file_path, 'r') as f:
for line in f:
line = line.strip()
# Ignore blank lines and comments
if not line or line.startswith("#"):
continue
if line.startswith("sonatypeUsername="):
username = line.split("=", 1)[1].strip()
elif line.startswith("sonatypePassword="):
password = line.split("=", 1)[1].strip()
if not username or not password:
print(f"Error: 'sonatypeUsername' or 'sonatypePassword' not found in {file_path}", file=sys.stderr)
sys.exit(1)
return username, password
except Exception as e:
print(f"Error reading properties file: {e}", file=sys.stderr)
sys.exit(1)
def generate_auth_token(username: str, password: str) -> str:
"""
Generates a Base64 encoded auth token from username and password.
"""
auth_string = f"{username}:{password}"
auth_bytes = auth_string.encode('utf-8')
token_bytes = base64.b64encode(auth_bytes)
return token_bytes.decode('utf-8')
def find_staging_repository(token: str) -> str:
"""
Finds the 'open' staging repository key from the Sonatype API.
"""
print("Searching for staging repository...")
url = f"{API_BASE_URL}/search/repositories"
headers = {
"Authorization": f"Bearer {token}",
"Accept": "application/json"
}
req = urllib.request.Request(url, headers=headers, method="GET")
try:
with urllib.request.urlopen(req) as response:
response_body = response.read().decode('utf-8')
data = json.loads(response_body)
repositories = data.get("repositories", [])
open_repositories = list(filter(lambda repo: repo.get("state") == "open", repositories))
if len(open_repositories) == 0:
print("Error: No 'open' staging repositories found.", file=sys.stderr)
sys.exit(1)
if len(open_repositories) > 1:
print(f"Error: Expected 1 'open' repository, but found {len(repositories)}.", file=sys.stderr)
sys.exit(1)
repo_key = open_repositories[0].get("key")
if not repo_key:
print("Error: Repository found, but it has no 'key'.", file=sys.stderr)
sys.exit(1)
return repo_key
except urllib.error.HTTPError as e:
# Handle HTTP errors (e.g., 401 Unauthorized, 404 Not Found, 500 Server Error)
print(f"Error during repository search: HTTP {e.code} {e.reason}", file=sys.stderr)
try:
# Try to read the error response body for more context
error_body = e.read().decode('utf-8')
print(f"Response body: {error_body}", file=sys.stderr)
except Exception:
pass # Ignore if we can't read the body
sys.exit(1)
except urllib.error.URLError as e:
# Handle network errors (e.g., connection refused)
print(f"Error during repository search: {e.reason}", file=sys.stderr)
sys.exit(1)
except json.JSONDecodeError:
print("Error: Failed to decode JSON response from server.", file=sys.stderr)
sys.exit(1)
def close_staging_repository(token: str, repo_key: str):
"""
Closes (promotes) the staging repository with the given key.
"""
print(f"Attempting to close staging repository: {repo_key}")
url = f"{API_BASE_URL}/upload/repository/{repo_key}"
headers = {"Authorization": f"Bearer {token}"}
req = urllib.request.Request(url, headers=headers, method="POST")
try:
with urllib.request.urlopen(req) as response:
print(f"Successfully submitted request. Server responded with: {response.status} {response.reason}")
print("It may take a few moments to process.")
except urllib.error.HTTPError as e:
print(f"Error closing repository: HTTP {e.code} {e.reason}", file=sys.stderr)
try:
error_body = e.read().decode('utf-8')
print(f"Response body: {error_body}", file=sys.stderr)
except Exception:
pass
sys.exit(1)
except urllib.error.URLError as e:
print(f"Error closing repository: {e.reason}", file=sys.stderr)
sys.exit(1)
def main():
username, password = get_gradle_credentials(PROPERTIES_PATH)
token = generate_auth_token(username, password)
print("Successfully generated auth token.")
repo_key = find_staging_repository(token)
print(f"Found staging repository: {repo_key}")
close_staging_repository(token, repo_key)
print("\nScript completed successfully.")
# --- Unit Tests ---
class TestSonatypeScript(unittest.TestCase):
@mock.patch('pathlib.Path.exists', return_value=True)
@mock.patch('builtins.open', new_callable=mock.mock_open,
read_data="# This is a comment\nsonatypeUsername=testuser\n\nsonatypePassword=testpass\nother=data")
def test_get_gradle_credentials_success(self, mock_file, mock_exists):
"""Tests successful credential parsing, ignoring comments."""
user, pw = get_gradle_credentials(pathlib.Path("/fake/path"))
self.assertEqual(user, "testuser")
self.assertEqual(pw, "testpass")
@mock.patch('pathlib.Path.exists', return_value=False)
def test_get_gradle_credentials_no_file(self, mock_exists):
"""Tests error exit when file is missing."""
with self.assertRaises(SystemExit) as cm:
get_gradle_credentials(pathlib.Path("/fake/path"))
@mock.patch('pathlib.Path.exists', return_value=True)
@mock.patch('builtins.open', new_callable=mock.mock_open, read_data="# Only comments\nsonatypeUsername=testuser")
def test_get_gradle_credentials_missing_key(self, mock_file, mock_exists):
"""Tests error exit when a key is missing."""
with self.assertRaises(SystemExit) as cm:
get_gradle_credentials(pathlib.Path("/fake/path"))
def test_generate_auth_token(self):
"""Tests the Base64 token encoding."""
token = generate_auth_token("foobar", "abc123")
# echo -n "foobar:abc123" | base64
self.assertEqual(token, "Zm9vYmFyOmFiYzEyMw==")
@mock.patch('urllib.request.urlopen')
def test_find_repository_success(self, mock_urlopen):
"""Tests finding exactly one open repository."""
mock_response = mock.Mock()
mock_response.status = 200
mock_response.reason = "OK"
mock_response.read.return_value = json.dumps({
"repositories": [{"key": "test-repo-key-123", "state": "open"}]
}).encode('utf-8')
mock_urlopen.return_value.__enter__.return_value = mock_response
key = find_staging_repository("fake-token")
self.assertEqual(key, "test-repo-key-123")
@mock.patch('urllib.request.urlopen')
def test_find_repository_success(self, mock_urlopen):
"""Tests finding exactly one open repository."""
mock_response = mock.Mock()
mock_response.status = 200
mock_response.reason = "OK"
mock_response.read.return_value = json.dumps({
"repositories": [{"key": "test-repo-key-123", "state": "open"}, {"key": "test-repo-key-456", "state": "closed"}]
}).encode('utf-8')
mock_urlopen.return_value.__enter__.return_value = mock_response
key = find_staging_repository("fake-token")
self.assertEqual(key, "test-repo-key-123")
@mock.patch('urllib.request.urlopen')
def test_find_repository_success(self, mock_urlopen):
"""Tests error exit when only a closed repository is found."""
mock_response = mock.Mock()
mock_response.status = 200
mock_response.reason = "OK"
mock_response.read.return_value = json.dumps({
"repositories": [{"key": "test-repo-key-123", "state": "closed"}]
}).encode('utf-8')
mock_urlopen.return_value.__enter__.return_value = mock_response
with self.assertRaises(SystemExit) as cm:
key = find_staging_repository("fake-token")
@mock.patch('urllib.request.urlopen')
def test_find_repository_not_found(self, mock_urlopen):
"""Tests error exit when zero repositories are found."""
mock_response = mock.Mock()
mock_response.status = 200
mock_response.read.return_value = json.dumps({"repositories": []}).encode('utf-8')
mock_urlopen.return_value.__enter__.return_value = mock_response
with self.assertRaises(SystemExit) as cm:
find_staging_repository("fake-token")
@mock.patch('urllib.request.urlopen')
def test_find_repository_too_many(self, mock_urlopen):
"""Tests error exit when multiple open repositories are found."""
mock_response = mock.Mock()
mock_response.status = 200
mock_response.read.return_value = json.dumps({
"repositories": [{"key": "key1", "state": "open"}, {"key": "key2", "state": "open"}]
}).encode('utf-8')
mock_urlopen.return_value.__enter__.return_value = mock_response
with self.assertRaises(SystemExit) as cm:
find_staging_repository("fake-token")
@mock.patch('urllib.request.urlopen')
def test_find_repository_http_error(self, mock_urlopen):
"""Tests error exit on a network HTTP error."""
# Mock an HTTPError
mock_urlopen.side_effect = urllib.error.HTTPError(
url='http://fake.com',
code=401,
msg="Unauthorized",
hdrs={},
fp=io.BytesIO(b'{"error":"bad token"}')
)
with self.assertRaises(SystemExit) as cm:
find_staging_repository("fake-token")
@mock.patch('urllib.request.urlopen')
def test_close_repository_success(self, mock_urlopen):
"""Tests successful repository close."""
mock_response = mock.Mock()
mock_response.status = 202 # 202 Accepted is a common response for POST
mock_response.reason = "Accepted"
mock_urlopen.return_value.__enter__.return_value = mock_response
close_staging_repository("fake-token", "test-repo-key")
# Check that the request object was created correctly
called_request = mock_urlopen.call_args[0][0]
self.assertEqual(called_request.full_url, f"{API_BASE_URL}/upload/repository/test-repo-key")
self.assertEqual(called_request.method, "POST")
self.assertEqual(called_request.headers["Authorization"], "Bearer fake-token")
@mock.patch('urllib.request.urlopen')
def test_close_repository_http_error(self, mock_urlopen):
"""Tests error exit on close network failure."""
mock_urlopen.side_effect = urllib.error.HTTPError(
url='http://fake.com',
code=500,
msg="Server Error",
hdrs={},
fp=io.BytesIO(b'{"error":"failed to close"}')
)
with self.assertRaises(SystemExit) as cm:
close_staging_repository("fake-token", "test-repo-key")
def run_unit_tests():
"""
Configures and runs the unit tests.
"""
print("Running unit tests...")
# We replace sys.argv to prevent unittest.main from
# trying to parse the 'test' argument.
original_argv = sys.argv
sys.argv = [original_argv[0]] # Keep only the script name
unittest.main()
sys.argv = original_argv # Restore original args
if __name__ == '__main__':
# Check if the user wants to run tests
if len(sys.argv) > 1 and sys.argv[1].lower() == 'test':
run_unit_tests()
else:
# Run the main script logic
main()
+60
View File
@@ -0,0 +1,60 @@
# Copyright (C) 2025 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.
#!/usr/bin/bash
set -e
GLTF_SAMPLE_ASSETS_COMMIT=${GITHUB_GLTF_SAMPLE_ASSETS_COMMIT:-d441dfdb87413ff412c620849a649d61789a470f}
COMMIT_HASH="${GLTF_SAMPLE_ASSETS_COMMIT}"
REPO_URL="https://github.com/KhronosGroup/glTF-Sample-Assets.git"
TARGET_DIR="gltf"
# The default directories to check out if none are specified
DEFAULT_SPARSE_PATHS=(
"Models/Box/"
"Models/Triangle/"
"Models/AnimatedCube/"
)
# Check if command-line arguments are provided
if [ "$#" -gt 0 ]; then
# If arguments are provided, use them as the paths
SPARSE_PATHS=()
for model_name in "$@"; do
SPARSE_PATHS+=("Models/${model_name}/")
done
echo "Downloading specified models: $@"
else
# Otherwise, use the default list
SPARSE_PATHS=("${DEFAULT_SPARSE_PATHS[@]}")
echo "No models specified, downloading default set."
fi
echo "Removing old directory..."
rm -rf "${TARGET_DIR}"
# Clone the repository using a "treeless" clone, which is highly efficient.
# --filter=tree:0: Clones only the repository structure without file content (no historical directory listings), making the initial clone very small.
# --no-checkout: Prevents automatically checking out the main branch. We will check out a specific commit later.
# --sparse: Initializes the repository for sparse checkout, allowing us to fetch only specific directories.
git clone --filter=tree:0 --no-checkout --sparse "${REPO_URL}" "${TARGET_DIR}"
cd "${TARGET_DIR}"
git sparse-checkout set "${SPARSE_PATHS[@]}"
echo "Checking out commit ${COMMIT_HASH}..."
git checkout "${COMMIT_HASH}"
echo "Successfully checked out the specified models into the '${TARGET_DIR}' directory."
+2 -1
View File
@@ -5,4 +5,5 @@ GITHUB_MESA_VERSION=24.2.1
GITHUB_LLVM_VERSION=16
GITHUB_NDK_VERSION=27.0.11718014
GITHUB_EMSDK_VERSION=3.1.60
GITHUB_VULKANSDK_VERSION=1.4.321.0
GITHUB_VULKANSDK_VERSION=1.4.321.0
GITHUB_GLTF_SAMPLE_ASSETS_COMMIT=d441dfdb87413ff412c620849a649d61789a470f
+25 -22
View File
@@ -212,7 +212,7 @@ when using textures.
This property can dramatically change the appearance of a surface. Non-metallic surfaces have
chromatic diffuse reflection and achromatic specular reflection (reflected light does not change
color). Metallic surfaces do not have any diffuse reflection and chromatic specular reflection
(reflected light takes on the color of the surfaced as defined by `baseColor`).
(reflected light takes on the color of the surfaced as defined by `baseColor`).
The effect of `metallic` is shown in figure [metallicProperty] (click on the image to see a
larger version).
@@ -248,7 +248,7 @@ The effect of `roughness` on metallic surfaces is shown in figure [roughnessCond
When refraction through an object is enabled (using a `refractonType` of `thin` or `solid`), the
`roughness` property will also affect the refractions, as shown in figure
[roughnessRefractionProperty] (click on the image to see a larger version).
![Figure [roughnessRefractionProperty]: Refractive sphere with `roughness` varying from 0.0
(left) to 1.0 (right)](images/materials/refraction_roughness.png)
@@ -307,7 +307,7 @@ The sheen color controls the color appearance and strength of an optional sheen
base layer described by the properties above. The sheen layer always sits below the clear coat layer
if such a layer is present.
The sheen layer can be used to represent cloth and fabric materials. Please refer to
The sheen layer can be used to represent cloth and fabric materials. Please refer to
section [Cloth model] for more information about cloth and fabric materials.
The effect of `sheenColor` is shown in figure [materialSheenColor]
@@ -520,14 +520,14 @@ light to bend further away from the initial path.
Table [commonMatIOR] describes acceptable refractive indices for various types of materials.
Material | IOR
Material | IOR
--------------------------:|:-----------------
Air | 1.0
Water | 1.33
Common liquids | 1.33 to 1.5
Common gemstones | 1.58 to 2.33
Plastics, glass | 1.5 to 1.58
Other dielectric materials | 1.33 to 1.58
Water | 1.33
Common liquids | 1.33 to 1.5
Common gemstones | 1.58 to 2.33
Plastics, glass | 1.5 to 1.58
Other dielectric materials | 1.33 to 1.58
[Table [commonMatIOR]: Index of refraction of common materials]
The appearance of a refractive material will greatly depend on the `refractionType` and
@@ -995,10 +995,10 @@ Value
name must be a valid GLSL identifier. Entries have an optional `precision`, which can be
one of `default` (best precision for the platform, typically `high` on desktop, `medium` on
mobile), `low`, `medium`, `high`. The type must be one of the types described in
table [materialParamsTypes]. For Android external textures, entries also have an optional
transformName parameter to specify the name of the material parameter that will be
table [materialParamsTypes]. For Android external textures, entries also have an optional
transformName parameter to specify the name of the material parameter that will be
used to expose the transform matrix associated with the external sampler. In iOS and Vulkan,
this will always be identity.
this will always be identity.
Type | Description
:----------------------|:---------------------------------
@@ -2476,14 +2476,17 @@ type aliases:
### Matrices
Name | Type | Description
:-----------------------------------|:--------:|:------------------------------------
**getViewFromWorldMatrix()** | float4x4 | Matrix that converts from world space to view/eye space
**getWorldFromViewMatrix()** | float4x4 | Matrix that converts from view/eye space to world space
**getClipFromViewMatrix()** | float4x4 | Matrix that converts from view/eye space to clip (NDC) space
**getViewFromClipMatrix()** | float4x4 | Matrix that converts from clip (NDC) space to view/eye space
**getClipFromWorldMatrix()** | float4x4 | Matrix that converts from world to clip (NDC) space
**getWorldFromClipMatrix()** | float4x4 | Matrix that converts from clip (NDC) space to world space
Name | Type | Description
:-----------------------------------------|:--------:|:------------------------------------
**getViewFromWorldMatrix()** | float4x4 | Matrix that converts from world space to view/eye space
**getWorldFromViewMatrix()** | float4x4 | Matrix that converts from view/eye space to world space
**getClipFromViewMatrix()** | float4x4 | Matrix that converts from view/eye space to clip (NDC) space
**getViewFromClipMatrix()** | float4x4 | Matrix that converts from clip (NDC) space to view/eye space
**getEyeFromViewMatrix()** | float4x4 | Matrix that converts from view space to eye space
**getEyeFromViewMatrix(int eyeIndex)** | float4x4 | Matrix that converts from view space to eye space for the eye referred to by eyeIndex
**getClipFromWorldMatrix()** | float4x4 | Matrix that converts from world to clip (NDC) space
**getClipFromWorldMatrix(int eyeIndex)** | float4x4 | Matrix that converts from world to clip (NDC) space for the eye referred to by eyeIndex
**getWorldFromClipMatrix()** | float4x4 | Matrix that converts from clip (NDC) space to world space
### Frame constants
@@ -2639,7 +2642,7 @@ standard skybox material. It produces a list of 2 parameters, named `showSun` an
respectively a boolean and a cubemap texture.
```text
$ matc --reflect parameters filament/src/materials/skybox.mat
$ matc --reflect parameters filament/src/materials/skybox.mat
{
"parameters": [
{
@@ -2655,7 +2658,7 @@ $ matc --reflect parameters filament/src/materials/skybox.mat
}
]
}
```
```
### --variant-filter
+267
View File
@@ -0,0 +1,267 @@
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Maven Release - Filament</title>
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<!-- Provide site root to javascript -->
<script>
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
</script>
<!-- Start loading toc.js asap -->
<script src="../toc.js"></script>
</head>
<body>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('light')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div style="display:flex;align-items:center;justify-content:center">
<img class="flogo" src="../images/filament_logo_small.png"></img>
</div>
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
</noscript>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<!-- Filament: disable themes because the markdeep part does not look good for dark themes -->
<!--
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
-->
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Filament</h1>
<div class="right-buttons">
<a href="https://github.com/google/filament" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="maven-release"><a class="header" href="#maven-release">Maven Release</a></h1>
<h2 id="register-for-a-sonatype-account"><a class="header" href="#register-for-a-sonatype-account">Register for a Sonatype Account</a></h2>
<p>First, you'll need to register for a Sonatype account at the <a href="https://central.sonatype.org/register/central-portal/">Central
Portal</a>.</p>
<p>To publish under the <code>com.google.android</code> namespace, you'll also need to email
<code>central-support@sonatype.com</code> with your account information to request access.</p>
<p>Then, generate a user token through the Sonatype website. Navigate to
<a href="https://central.sonatype.com/account">https://central.sonatype.com/account</a> and select <strong>Generate
User Token</strong>.</p>
<p>Finally, add the generated token credentials to <code>~/.gradle/gradle.properties</code>. (Note: these are
different from the credentials used to log into your Sonatype account):</p>
<pre><code class="language-gradle"># Generated Sonatype token
sonatypeUsername=&lt;username&gt;
sonatypePassword=&lt;password&gt;
</code></pre>
<hr />
<h2 id="signing-key"><a class="header" href="#signing-key">Signing Key</a></h2>
<p>All release artifacts must be signed. You'll need to create an OpenPGP key pair. See Gradle's
documentation on <a href="https://docs.gradle.org/current/userguide/signing_plugin.html#sec:signatory_credentials">Signatory
credentials</a>
for instructions.</p>
<p>Update <code>~/.gradle/gradle.properties</code> with your new key's credentials:</p>
<pre><code class="language-gradle">signing.keyId=&lt;key id&gt;
signing.password=&lt;key password&gt;
signing.secretKeyRingFile=&lt;secret key ring file&gt;
</code></pre>
<hr />
<h2 id="build-the-android-release"><a class="header" href="#build-the-android-release">Build the Android Release</a></h2>
<p>Make sure <code>JAVA_HOME</code> is set correctly. For example:</p>
<pre><code class="language-bash">export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home
./build.sh -C -i -p android release
</code></pre>
<hr />
<h2 id="publish-to-sonatype"><a class="header" href="#publish-to-sonatype">Publish to Sonatype</a></h2>
<h3 id="a-note-on-the-legacy-staging-service"><a class="header" href="#a-note-on-the-legacy-staging-service">A Note on the Legacy Staging Service</a></h3>
<p>Previously, Filament was published to Maven via OSSRH (Open Source Software Repository Hosting). In
2025, this service was <a href="https://central.sonatype.org/pages/ossrh-eol/">sunsetted</a>. Now, we use
Sonatype's <a href="https://central.sonatype.org/">Central Publisher Portal</a>.</p>
<p>The new Central Publisher Portal does not officially support Gradle. However, Sonatype provides a
staging API compatibility service, which works with Filament's Gradle setup.</p>
<hr />
<h3 id="1-upload-to-the-staging-api-compatibility-service"><a class="header" href="#1-upload-to-the-staging-api-compatibility-service">1. Upload to the Staging API Compatibility Service</a></h3>
<pre><code class="language-bash">cd android
./gradlew publishToSonatype
</code></pre>
<h3 id="2-move-the-repository-to-the-central-publisher-portal"><a class="header" href="#2-move-the-repository-to-the-central-publisher-portal">2. Move the Repository to the Central Publisher Portal</a></h3>
<p>We have a script to automate this. It reads the <code>sonatypeUsername</code> and <code>sonatypePassword</code> from your
<code>~/.gradle/gradle.properties</code> file.</p>
<pre><code class="language-bash">python3 build/common/close-sonatype-staging-repository.py
</code></pre>
<h3 id="3-publish-the-release-on-sonatype"><a class="header" href="#3-publish-the-release-on-sonatype">3. Publish the Release on Sonatype</a></h3>
<p>Navigate to <a href="https://central.sonatype.com/publishing/deployments">Maven Central Repository Deployments</a>.</p>
<p>Here, you should see a new deployment with a <strong>Validated</strong> status and all your artifacts listed. Click
the <strong>Publish</strong> button to publish the artifacts. It typically takes around 5 minutes after clicking
<strong>Publish</strong> for the artifacts to go live.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../build/windows_android.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/contributing.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../build/windows_android.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/contributing.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js"></script>
<script src="../mark.min.js"></script>
<script src="../searcher.js"></script>
<script src="../clipboard.min.js"></script>
<script src="../highlight.js"></script>
<script src="../book.js"></script>
<!-- Custom JS scripts -->
</div>
</body>
</html>
+2 -2
View File
@@ -273,7 +273,7 @@ copy filament-android\build\outputs\aar\filament-android-release.aar ..\..\out\
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/contributing.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../build/maven_release.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
@@ -287,7 +287,7 @@ copy filament-android\build\outputs\aar\filament-android-release.aar ..\..\out\
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/contributing.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../build/maven_release.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
+1 -1
View File
@@ -434,7 +434,7 @@ to create a quick localhost server:</p>
<p>Alternatively, if you have node installed you can use the
<a href="https://www.npmjs.com/package/live-server">live-server</a> package, which automatically refreshes the
web page when it detects a change.</p>
<p>Each sample app has its own handwritten html file. Additionally the server folder contains assets
<p>Each sample app has its own handwritten html file. Additionally, the server folder contains assets
such as meshes, textures, and materials.</p>
<h2 id="running-the-native-samples"><a class="header" href="#running-the-native-samples">Running the native samples</a></h2>
<p>The <code>samples/</code> directory contains several examples of how to use Filament with SDL2.</p>
+18 -6
View File
@@ -179,7 +179,7 @@ Google code style and is derived from the Java code style, but not quite.</p>
<li>class access modifiers are not indented</li>
<li>last line of <code>.cpp</code> or <code>.h</code> file must be an empty line</li>
</ul>
<pre><code>for (int i = 0; i &lt; max; i++) {
<pre><code class="language-c++">for (int i = 0; i &lt; max; i++) {
}
class Foo {
@@ -227,11 +227,23 @@ src/data.inc
<li><code>public</code> class attributes <em>are not</em> prefixed</li>
<li>class attributes and methods are lower camelcase</li>
</ul>
<pre><code>extern int gGlobalWarming;
<pre><code class="language-c++">extern int gGlobalWarming;
class FooBar {
public:
void methodName();
FooBar(int attributeName, int sizeInBytes)
: mAttributeName(attributeName),
sizeInBytes(sizeInBytes) {}
void reallyLongMethodNameWithLotsOfArguments(bool argument1,
int someSecondArgument, int bestArgument) {
std::pair&lt;bool, int&gt; pair = {
argument1,
argument2,
};
// etc
}
int sizeInBytes;
private:
int mAttributeName;
@@ -248,7 +260,7 @@ private:
<li>always include the copyright notice at the top of every file</li>
<li>make sure the date is correct</li>
</ul>
<pre><code>/*
<pre><code class="language-c++">/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -293,7 +305,7 @@ conversely containers and algorithms are not allowed. There are exceptions such
</li>
</ul>
<p><em>Sorting the headers is important to help catching missing <code>#include</code> directives.</em></p>
<pre><code>/*
<pre><code class="language-c++">/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -336,7 +348,7 @@ from other string types.</li>
<ul>
<li>Use <code>auto</code> only when the type appears on the same line or with iterators and lambdas.</li>
</ul>
<pre><code>auto foo = new Foo();
<pre><code class="language-c++">auto foo = new Foo();
for (auto&amp; i : collection) { }
</code></pre>
+2 -2
View File
@@ -209,7 +209,7 @@ as possible. The current external dependencies of the runtime library include:</
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../build/windows_android.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../build/maven_release.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
@@ -223,7 +223,7 @@ as possible. The current external dependencies of the runtime library include:</
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../build/windows_android.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../build/maven_release.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
+2 -2
View File
@@ -181,7 +181,7 @@ important for <code>matc</code> (material compiler).</p>
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.64.0'
implementation 'com.google.android.filament:filament-android:1.66.0'
}
</code></pre>
<p>Here are all the libraries available in the group <code>com.google.android.filament</code>:</p>
@@ -196,7 +196,7 @@ dependencies {
</div>
<h3 id="ios"><a class="header" href="#ios">iOS</a></h3>
<p>iOS projects can use CocoaPods to install the latest release:</p>
<pre><code class="language-shell">pod 'Filament', '~&gt; 1.64.0'
<pre><code class="language-shell">pod 'Filament', '~&gt; 1.66.0'
</code></pre>
<h2 id="documentation"><a class="header" href="#documentation">Documentation</a></h2>
<ul>
+341
View File
@@ -0,0 +1,341 @@
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>renderdiff - Filament</title>
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<!-- Provide site root to javascript -->
<script>
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
</script>
<!-- Start loading toc.js asap -->
<script src="../toc.js"></script>
</head>
<body>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('light')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div style="display:flex;align-items:center;justify-content:center">
<img class="flogo" src="../images/filament_logo_small.png"></img>
</div>
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
</noscript>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<!-- Filament: disable themes because the markdeep part does not look good for dark themes -->
<!--
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
-->
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Filament</h1>
<div class="right-buttons">
<a href="https://github.com/google/filament" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="rendering-difference-test"><a class="header" href="#rendering-difference-test">Rendering Difference Test</a></h1>
<p>We created a few scripts to run <code>gltf_viewer</code> and produce headless renderings.</p>
<p>This is mainly useful for continuous integration where GPUs are generally not available on cloud
machines. To perform software rasterization, these scripts are centered around <a href="https://docs.mesa3d.org">Mesa</a>'s
software rasterizers, but nothing bars us from using another rasterizer like <a href="https://github.com/google/swiftshader">SwiftShader</a>.
Additionally, we should be able to use GPUs where available (though this is more of a future
work).</p>
<p>The script <code>render.py</code> contains the core logic for taking input parameters (such as the test
description file) and then running gltf_viewer to produce the renderings.</p>
<p>In the <code>test</code> directory is a list of test descriptions that are specified in json. Please see
<code>sample.json</code> to parse the structure.</p>
<h2 id="setting-up-python"><a class="header" href="#setting-up-python">Setting up python</a></h2>
<p>The <code>renderdiff</code> project uses <code>python</code> extensively. To install the dependencies for producing
renderings, do the following step</p>
<ul>
<li>Set up a virtual environment (from the root directory)
<pre><code>python3 -m venv venv
. ./venv/bin/activate
</code></pre>
</li>
<li>Install the rendering dependencies
<pre><code>pip install -r test/renderdiff/src/rendering_requirements.txt
</code></pre>
</li>
<li>Install the viewer depdencies
<pre><code>pip install -r test/renderdiff/src/viewer_requirements.txt
</code></pre>
</li>
<li>For the commands in the following section, do not exit the virtual environment. Once you've
completed all your work, you can exit with
<pre><code>deactivate
</code></pre>
</li>
</ul>
<h2 id="running-the-test-locally"><a class="header" href="#running-the-test-locally">Running the test locally</a></h2>
<ul>
<li>To run the same presbumit as <a href="presubmit-renderdiff"><code>test-renderdiff</code></a>, you can do
<pre><code>bash test/renderdiff/local_test.sh
</code></pre>
</li>
<li>This script will generate the renderings based on the current state of your repo.
Additionally, it will also compare the generated images with corresponding images in the
golden repo.</li>
<li>To just render without running the test, you could use the following script
<pre><code>bash test/renderdiff/generate.sh
</code></pre>
</li>
</ul>
<h2 id="command-line-options"><a class="header" href="#command-line-options">Command-line Options</a></h2>
<p>You can control the behavior of the test scripts with the following flags passed to <code>local_test.sh</code>:</p>
<ul>
<li><code>--test_filter=&lt;filter&gt;</code>: Run a subset of tests. The filter supports wildcards (<code>*</code>) to match test names.</li>
<li><code>--no_rebuild</code>: Skip rebuilding the <code>gltf_viewer</code> executable.</li>
<li><code>--num_threads=&lt;number&gt;</code>: Set the number of threads for rendering. If not set, the system's default is used.</li>
</ul>
<p>For example, to run all <code>MSAA</code> tests without rebuilding and using 8 threads:</p>
<pre><code>bash test/renderdiff/local_test.sh --test_filter='MSAA.*.*' --no_rebuild --num_threads=8
</code></pre>
<h2 id="update-the-golden-images"><a class="header" href="#update-the-golden-images">Update the golden images</a></h2>
<p>The golden images are stored in a github repository:
https://github.com/google/filament-assets. Filament team members should have access to write
to the repository. A typical flow for updating the goldens is to upload your changed images
into <strong>branch</strong> of <code>filament-assets</code>. This branch is paired with a PR or commit on the
<code>filament</code> repo.</p>
<p>As an example, imagine I am working on a PR, and I've uploaded my change, which is in a
branch called <code>my-pr-branch</code>, to <code>filament</code>. This PR requires updating the golden. We would do
it in the following fashion</p>
<h3 id="using-a-script-to-update-the-golden-repo"><a class="header" href="#using-a-script-to-update-the-golden-repo">Using a script to update the golden repo</a></h3>
<ul>
<li>Run interactive mode in the <code>update_golden.py</code> script.
<pre><code>python3 test/renderdiff/src/update_golden.py
</code></pre>
</li>
<li>This will guide you through a series of steps to push the changes to a remote branch on
<code>filament-assets</code>.</li>
</ul>
<h3 id="manually-updating-the-golden-repo"><a class="header" href="#manually-updating-the-golden-repo">Manually updating the golden repo</a></h3>
<ul>
<li>Check out the golden repo
<pre><code>git clone git@github.com:google/filament-assets.git
</code></pre>
</li>
<li>Create a branch on the golden repo
<pre><code>cd filament-assets
git switch -c my-pr-branch-golden
</code></pre>
</li>
<li>Copy the new images to their appropriate place in <code>filament-assets</code></li>
<li>Push the <code>filament-assets</code> working branch to remote
<pre><code>git push origin my-pr-branch-golden
</code></pre>
</li>
<li>In the commit message of your working branch on <code>filament</code>, add the following line
<pre><code>RDIFF_BBRANCH=my-pr-branch-golden
</code></pre>
</li>
</ul>
<p>Doing the above has multiple effects:</p>
<ul>
<li>The presubmit test <a href="https://github.com/google/filament/blob/e85dfe75c86106a05019e13ccdbef67e030af675/.github/workflows/presubmit.yml#L118"><code>test-renderdiff</code></a> will test against the provided
branch of the golden repo (i.e. <code>my-pr-branch-golden</code>).</li>
<li>If the PR is merged, then there is another workflow that will merge <code>my-pr-branch-golden</code>
to the <code>main</code> branch of the golden repo.</li>
</ul>
<h2 id="viewing-test-results"><a class="header" href="#viewing-test-results">Viewing test results</a></h2>
<p>We provide a viewer for looking at the result of a test run. The viewer is a webapp that can
be used by pointing your browser to a localhost port. If you input the viewer with a PR or a
directory, it will parse the test result and show the results and the rendered and/or golden
images.</p>
<p><img src="../images/renderdiff_example.png" alt="Viewer" /></p>
<p>To run the viewer of a test output directory that has been generated locally, you would run
the following</p>
<pre><code>python3 test/renderdiff/src/viewer.py --diff=[test output]
</code></pre>
<p>where <code>[test output]</code> is a directory containing the <code>compare_results.json</code> of the test run.
For example, it could be <code>out/renderdiff/diffs/presubmit</code> for the standard path to the
<code>presubmit</code> test output.</p>
<p>To see the results of a Pull Request initiated test run, you would do the following</p>
<pre><code>python3 test/renderdiff/src/viewer.py --pr_number=[PR #] --github_token=[github token]
</code></pre>
<p>where <code>[PR #]</code> is the numeric ID of your pull request, and the <code>[github token]</code> is an acess
token that you (as a github user) needs to generate (<a href="https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens">reference</a>).</p>
<p>To see the results of a specific run, you would do the following</p>
<pre><code>python3 test/renderdiff/src/viewer.py --run_number=[RUN #] --github_token=[github token]
</code></pre>
<p>where <code>[RUN #]</code> is the numeric ID of the run. You can find the run number in the URL of the
GitHub Actions page. For example, in the URL
<code>https://github.com/google/filament/actions/runs/18023632663/job/51286323708?pr=9264</code>,
the run number is <code>18023632663</code>.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../notes/tests.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../notes/libs.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../notes/tests.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../notes/libs.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js"></script>
<script src="../mark.min.js"></script>
<script src="../searcher.js"></script>
<script src="../clipboard.min.js"></script>
<script src="../highlight.js"></script>
<script src="../book.js"></script>
<!-- Custom JS scripts -->
</div>
</body>
</html>
+1 -1
View File
@@ -162,7 +162,7 @@
<p>This tool makes it easy to analyze the composition of Android applications that use Filament.</p>
<ul>
<li>Filament materials are shown in the treemap if <code>resgen --json</code> was used in the build.</li>
<li>The input path can be a so file, folder, or zip archive (apk or aar).</li>
<li>The input path can be a <code>.so</code> or <code>.a</code> file, a folder, or a zip archive (apk or aar).</li>
<li>If the path is a zip or folder, interactively finds the file to analyze.</li>
<li>The generated web report is a self-contained HTML file.</li>
<li>Reports the gzipped size of all Filament materials.</li>
Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

+4 -4
View File
@@ -178,9 +178,9 @@ content:counter(h1) "."counter(h2) "."counter(h3) "."counter(h4) "."counter(h5)
counter-increment: h6;margin-right:10px}
</style><style>.hljs{display:block;overflow-x:auto;padding:0.5em;background:#fff;color:#000;-webkit-text-size-adjust:none}.hljs-comment{color:#006a00}.hljs-keyword{color:#02E}.hljs-literal,.nginx .hljs-title{color:#aa0d91}.method,.hljs-list .hljs-title,.hljs-tag .hljs-title,.setting .hljs-value,.hljs-winutils,.tex .hljs-command,.http .hljs-title,.hljs-request,.hljs-status,.hljs-name{color:#008}.hljs-envvar,.tex .hljs-special{color:#660}.hljs-string{color:#c41a16}.hljs-tag .hljs-value,.hljs-cdata,.hljs-filter .hljs-argument,.hljs-attr_selector,.apache .hljs-cbracket,.hljs-date,.hljs-regexp{color:#080}.hljs-sub .hljs-identifier,.hljs-pi,.hljs-tag,.hljs-tag .hljs-keyword,.hljs-decorator,.ini .hljs-title,.hljs-shebang,.hljs-prompt,.hljs-hexcolor,.hljs-rule .hljs-value,.hljs-symbol,.hljs-symbol .hljs-string,.hljs-number,.css .hljs-function,.hljs-function .hljs-title,.coffeescript .hljs-attribute{color:#A0C}.hljs-function .hljs-title{font-weight:bold;color:#000}.hljs-class .hljs-title,.smalltalk .hljs-class,.hljs-type,.hljs-typename,.hljs-tag .hljs-attribute,.hljs-doctype,.hljs-class .hljs-id,.hljs-built_in,.setting,.hljs-params,.clojure .hljs-attribute{color:#5c2699}.hljs-variable{color:#3f6e74}.css .hljs-tag,.hljs-rule .hljs-property,.hljs-pseudo,.hljs-subst{color:#000}.css .hljs-class,.css .hljs-id{color:#9b703f}.hljs-value .hljs-important{color:#ff7700;font-weight:bold}.hljs-rule .hljs-keyword{color:#c5af75}.hljs-annotation,.apache .hljs-sqbracket,.nginx .hljs-built_in{color:#9b859d}.hljs-preprocessor,.hljs-preprocessor *,.hljs-pragma{color:#643820}.tex .hljs-formula{background-color:#eee;font-style:italic}.diff .hljs-header,.hljs-chunk{color:#808080;font-weight:bold}.diff .hljs-change{background-color:#bccff9}.hljs-addition{background-color:#baeeba}.hljs-deletion{background-color:#ffc8bd}.hljs-comment .hljs-doctag{font-weight:bold}.method .hljs-id{color:#000}</style><style>div.title { padding-top: 40px; } div.afterTitles { height: 15px; }</style><meta charset="utf-8"></p>
<style>img { max-width: 100%; }</style>
<script type="text/x-mathjax-config">MathJax.Hub.Config({ TeX: { equationNumbers: {autoNumber: "AMS"} } });</script><span style="display:none">$$\newcommand{\n}{\hat{n}}\newcommand{\thetai}{\theta_\mathrm{i}}\newcommand{\thetao}{\theta_\mathrm{o}}\newcommand{\d}[1]{\mathrm{d}#1}\newcommand{\w}{\hat{\omega}}\newcommand{\wi}{\w_\mathrm{i}}\newcommand{\wo}{\w_\mathrm{o}}\newcommand{\wh}{\w_\mathrm{h}}\newcommand{\Li}{L_\mathrm{i}}\newcommand{\Lo}{L_\mathrm{o}}\newcommand{\Le}{L_\mathrm{e}}\newcommand{\Lr}{L_\mathrm{r}}\newcommand{\Lt}{L_\mathrm{t}}\newcommand{\O}{\mathrm{O}}\newcommand{\degrees}{{^{\large\circ}}}\newcommand{\T}{\mathsf{T}}\newcommand{\mathset}[1]{\mathbb{#1}}\newcommand{\Real}{\mathset{R}}\newcommand{\Integer}{\mathset{Z}}\newcommand{\Boolean}{\mathset{B}}\newcommand{\Complex}{\mathset{C}}\newcommand{\un}[1]{\,\mathrm{#1}}$$
<p><span style="display:none">$$\newcommand{\n}{\hat{n}}\newcommand{\thetai}{\theta_\mathrm{i}}\newcommand{\thetao}{\theta_\mathrm{o}}\newcommand{\d}[1]{\mathrm{d}#1}\newcommand{\w}{\hat{\omega}}\newcommand{\wi}{\w_\mathrm{i}}\newcommand{\wo}{\w_\mathrm{o}}\newcommand{\wh}{\w_\mathrm{h}}\newcommand{\Li}{L_\mathrm{i}}\newcommand{\Lo}{L_\mathrm{o}}\newcommand{\Le}{L_\mathrm{e}}\newcommand{\Lr}{L_\mathrm{r}}\newcommand{\Lt}{L_\mathrm{t}}\newcommand{\O}{\mathrm{O}}\newcommand{\degrees}{{^{\large\circ}}}\newcommand{\T}{\mathsf{T}}\newcommand{\mathset}[1]{\mathbb{#1}}\newcommand{\Real}{\mathset{R}}\newcommand{\Integer}{\mathset{Z}}\newcommand{\Boolean}{\mathset{B}}\newcommand{\Complex}{\mathset{C}}\newcommand{\un}[1]{,\mathrm{#1}}$$
</span>
<span class="md"><p><title>Physically Based Rendering in Filament</title><div class="title"> Physically Based Rendering in Filament </div>
<span class="md"><p><title>Physically Based Rendering in Filament</title><div class="title"> Physically Based Rendering in Filament </div></p>
<div class="afterTitles"></div>
</p><p>
</p>
@@ -2060,7 +2060,7 @@ In practice only 4 or 9 coefficients (i.e.: 2 or 3 bands) are enough for \(\cosT
In practice we pre-convolve \(\Lt\) with \(\cosTheta\) and pre-scale these coefficients by the basis scaling factors \(K_l^m\) so that the reconstruction code is as simple as possible in the shader:
</p><a class="target" name="listing_irradiancesh">&nbsp;</a><pre class="listing tilde"><code><span class="line"></span>vec3 irradianceSH(vec3 n) {
<span class="line"></span> // uniform vec3 sphericalHarmonics<span class="hljs-selector-attr">[9]</span>
<span class="line"></span> // We can use only the first <span class="hljs-number">2</span> bands for better performance
<span class="line"></span> // We can <span class="hljs-selector-tag">use</span> only the first <span class="hljs-number">2</span> bands for better performance
<span class="line"></span> return
<span class="line"></span> sphericalHarmonics<span class="hljs-selector-attr">[0]</span>
<span class="line"></span> + sphericalHarmonics<span class="hljs-selector-attr">[1]</span> * (n<span class="hljs-selector-class">.y</span>)
@@ -4395,7 +4395,7 @@ For Fast Realistic Image Display. <em class="asterisk">SIGGRAPH '00 Proceedings
</div><div class="bib">[<a class="target" name="citation-schlick94">&nbsp;</a><b>Schlick94</b>] Christophe Schlick. 1994. An Inexpensive BRDF Model for Physically-Based Rendering. <em class="asterisk">Computer Graphics Forum</em>, 13 (3), 233–246.
</div><div class="bib">[<a class="target" name="citation-walter07">&nbsp;</a><b>Walter07</b>] Bruce Walter et al. 2007. Microfacet Models for Refraction through Rough Surfaces. <em class="asterisk">Proceedings of the Eurographics Symposium on Rendering</em>.
</div>
</sample></float></sample></float></float></p></span><div id="mdContextMenu" style="visibility:hidden"></div><div class="markdeepFooter"><i>formatted by <a href="https://casual-effects.com/markdeep" style="color:#999">Markdeep&nbsp;1.18&nbsp;&nbsp;</a></i><div style="display:inline-block;font-size:13px;font-family:'Times New Roman',serif;vertical-align:middle;transform:translate(-3px,-1px)rotate(135deg);">&#x2712;</div></div><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.6/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</sample></float></sample></float></float></p></span><div id="mdContextMenu" style="visibility:hidden"></div><div class="markdeepFooter"><i>formatted by <a href="https://casual-effects.com/markdeep" style="color:#999">Markdeep&nbsp;1.18&nbsp;&nbsp;</a></i><div style="display:inline-block;font-size:13px;font-family:'Times New Roman',serif;vertical-align:middle;transform:translate(-3px,-1px)rotate(135deg);">&#x2712;</div></div><script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
+12 -9
View File
@@ -178,9 +178,9 @@ content:counter(h1) "."counter(h2) "."counter(h3) "."counter(h4) "."counter(h5)
counter-increment: h6;margin-right:10px}
</style><style>.hljs{display:block;overflow-x:auto;padding:0.5em;background:#fff;color:#000;-webkit-text-size-adjust:none}.hljs-comment{color:#006a00}.hljs-keyword{color:#02E}.hljs-literal,.nginx .hljs-title{color:#aa0d91}.method,.hljs-list .hljs-title,.hljs-tag .hljs-title,.setting .hljs-value,.hljs-winutils,.tex .hljs-command,.http .hljs-title,.hljs-request,.hljs-status,.hljs-name{color:#008}.hljs-envvar,.tex .hljs-special{color:#660}.hljs-string{color:#c41a16}.hljs-tag .hljs-value,.hljs-cdata,.hljs-filter .hljs-argument,.hljs-attr_selector,.apache .hljs-cbracket,.hljs-date,.hljs-regexp{color:#080}.hljs-sub .hljs-identifier,.hljs-pi,.hljs-tag,.hljs-tag .hljs-keyword,.hljs-decorator,.ini .hljs-title,.hljs-shebang,.hljs-prompt,.hljs-hexcolor,.hljs-rule .hljs-value,.hljs-symbol,.hljs-symbol .hljs-string,.hljs-number,.css .hljs-function,.hljs-function .hljs-title,.coffeescript .hljs-attribute{color:#A0C}.hljs-function .hljs-title{font-weight:bold;color:#000}.hljs-class .hljs-title,.smalltalk .hljs-class,.hljs-type,.hljs-typename,.hljs-tag .hljs-attribute,.hljs-doctype,.hljs-class .hljs-id,.hljs-built_in,.setting,.hljs-params,.clojure .hljs-attribute{color:#5c2699}.hljs-variable{color:#3f6e74}.css .hljs-tag,.hljs-rule .hljs-property,.hljs-pseudo,.hljs-subst{color:#000}.css .hljs-class,.css .hljs-id{color:#9b703f}.hljs-value .hljs-important{color:#ff7700;font-weight:bold}.hljs-rule .hljs-keyword{color:#c5af75}.hljs-annotation,.apache .hljs-sqbracket,.nginx .hljs-built_in{color:#9b859d}.hljs-preprocessor,.hljs-preprocessor *,.hljs-pragma{color:#643820}.tex .hljs-formula{background-color:#eee;font-style:italic}.diff .hljs-header,.hljs-chunk{color:#808080;font-weight:bold}.diff .hljs-change{background-color:#bccff9}.hljs-addition{background-color:#baeeba}.hljs-deletion{background-color:#ffc8bd}.hljs-comment .hljs-doctag{font-weight:bold}.method .hljs-id{color:#000}</style><style>div.title { padding-top: 40px; } div.afterTitles { height: 15px; }</style><meta charset="utf-8"></p>
<style>img { max-width: 100%; }</style>
<script type="text/x-mathjax-config">MathJax.Hub.Config({ TeX: { equationNumbers: {autoNumber: "AMS"} } });</script><span style="display:none">$$\newcommand{\n}{\hat{n}}\newcommand{\thetai}{\theta_\mathrm{i}}\newcommand{\thetao}{\theta_\mathrm{o}}\newcommand{\d}[1]{\mathrm{d}#1}\newcommand{\w}{\hat{\omega}}\newcommand{\wi}{\w_\mathrm{i}}\newcommand{\wo}{\w_\mathrm{o}}\newcommand{\wh}{\w_\mathrm{h}}\newcommand{\Li}{L_\mathrm{i}}\newcommand{\Lo}{L_\mathrm{o}}\newcommand{\Le}{L_\mathrm{e}}\newcommand{\Lr}{L_\mathrm{r}}\newcommand{\Lt}{L_\mathrm{t}}\newcommand{\O}{\mathrm{O}}\newcommand{\degrees}{{^{\large\circ}}}\newcommand{\T}{\mathsf{T}}\newcommand{\mathset}[1]{\mathbb{#1}}\newcommand{\Real}{\mathset{R}}\newcommand{\Integer}{\mathset{Z}}\newcommand{\Boolean}{\mathset{B}}\newcommand{\Complex}{\mathset{C}}\newcommand{\un}[1]{\,\mathrm{#1}}$$
<p><span style="display:none">$$\newcommand{\n}{\hat{n}}\newcommand{\thetai}{\theta_\mathrm{i}}\newcommand{\thetao}{\theta_\mathrm{o}}\newcommand{\d}[1]{\mathrm{d}#1}\newcommand{\w}{\hat{\omega}}\newcommand{\wi}{\w_\mathrm{i}}\newcommand{\wo}{\w_\mathrm{o}}\newcommand{\wh}{\w_\mathrm{h}}\newcommand{\Li}{L_\mathrm{i}}\newcommand{\Lo}{L_\mathrm{o}}\newcommand{\Le}{L_\mathrm{e}}\newcommand{\Lr}{L_\mathrm{r}}\newcommand{\Lt}{L_\mathrm{t}}\newcommand{\O}{\mathrm{O}}\newcommand{\degrees}{{^{\large\circ}}}\newcommand{\T}{\mathsf{T}}\newcommand{\mathset}[1]{\mathbb{#1}}\newcommand{\Real}{\mathset{R}}\newcommand{\Integer}{\mathset{Z}}\newcommand{\Boolean}{\mathset{B}}\newcommand{\Complex}{\mathset{C}}\newcommand{\un}[1]{,\mathrm{#1}}$$
</span>
<span class="md"><p><title>Filament Materials Guide</title><div class="title"> Filament Materials Guide </div>
<span class="md"><p><title>Filament Materials Guide</title><div class="title"> Filament Materials Guide </div></p>
<div class="afterTitles"></div>
</p><p>
</p>
@@ -504,7 +504,7 @@ when using textures.</p>
This property can dramatically change the appearance of a surface. Non-metallic surfaces have
chromatic diffuse reflection and achromatic specular reflection (reflected light does not change
color). Metallic surfaces do not have any diffuse reflection and chromatic specular reflection
(reflected light takes on the color of the surfaced as defined by <code>baseColor</code>).
(reflected light takes on the color of the surfaced as defined by <code>baseColor</code>).
</p><p>
The effect of <code>metallic</code> is shown in <a href="#figure_metallicproperty" target="_self">figure&nbsp;1</a> (click on the image to see a
larger version).
@@ -597,7 +597,7 @@ indices.
base layer described by the properties above. The sheen layer always sits below the clear coat layer
if such a layer is present.</p>
</p><p>
The sheen layer can be used to represent cloth and fabric materials. Please refer to
The sheen layer can be used to represent cloth and fabric materials. Please refer to
section <a href="#toc3.3" target="_self">3.3</a> for more information about cloth and fabric materials.
</p><p>
The effect of <code>sheenColor</code> is shown in <a href="#figure_materialsheencolor" target="_self">figure&nbsp;7</a>
@@ -1220,10 +1220,10 @@ non-shader data.</p>
name must be a valid GLSL identifier. Entries have an optional <code>precision</code>, which can be
one of <code>default</code> (best precision for the platform, typically <code>high</code> on desktop, <code>medium</code> on
mobile), <code>low</code>, <code>medium</code>, <code>high</code>. The type must be one of the types described in
<a href="#table_materialparamstypes" target="_self">table&nbsp;14</a>. For Android external textures, entries also have an optional
transformName parameter to specify the name of the material parameter that will be
<a href="#table_materialparamstypes" target="_self">table&nbsp;14</a>. For Android external textures, entries also have an optional
transformName parameter to specify the name of the material parameter that will be
used to expose the transform matrix associated with the external sampler. In iOS and Vulkan,
this will always be identity.
this will always be identity.
</p></dd></dl><div class='table'>
<a class="target" name="table_materialparamstypes">&nbsp;</a><table class="table longtable"><tr><th style="text-align:left"> Type </th><th style="text-align:left"> Description </th></tr>
<tr><td style="text-align:left"> bool </td><td style="text-align:left"> Single boolean </td></tr>
@@ -2361,7 +2361,10 @@ type aliases:</p>
<tr><td style="text-align:left"> <strong class="asterisk">getWorldFromViewMatrix()</strong> </td><td style="text-align:center"> float4&times;4 </td><td style="text-align:left"> Matrix that converts from view/eye space to world space </td></tr>
<tr><td style="text-align:left"> <strong class="asterisk">getClipFromViewMatrix()</strong> </td><td style="text-align:center"> float4&times;4 </td><td style="text-align:left"> Matrix that converts from view/eye space to clip (NDC) space </td></tr>
<tr><td style="text-align:left"> <strong class="asterisk">getViewFromClipMatrix()</strong> </td><td style="text-align:center"> float4&times;4 </td><td style="text-align:left"> Matrix that converts from clip (NDC) space to view/eye space </td></tr>
<tr><td style="text-align:left"> <strong class="asterisk">getEyeFromViewMatrix()</strong> </td><td style="text-align:center"> float4&times;4 </td><td style="text-align:left"> Matrix that converts from view space to eye space </td></tr>
<tr><td style="text-align:left"> <strong class="asterisk">getEyeFromViewMatrix(int eyeIndex)</strong> </td><td style="text-align:center"> float4&times;4 </td><td style="text-align:left"> Matrix that converts from view space to eye space for the eye referred to by eyeIndex </td></tr>
<tr><td style="text-align:left"> <strong class="asterisk">getClipFromWorldMatrix()</strong> </td><td style="text-align:center"> float4&times;4 </td><td style="text-align:left"> Matrix that converts from world to clip (NDC) space </td></tr>
<tr><td style="text-align:left"> <strong class="asterisk">getClipFromWorldMatrix(int eyeIndex)</strong> </td><td style="text-align:center"> float4&times;4 </td><td style="text-align:left"> Matrix that converts from world to clip (NDC) space for the eye referred to by eyeIndex </td></tr>
<tr><td style="text-align:left"> <strong class="asterisk">getWorldFromClipMatrix()</strong> </td><td style="text-align:center"> float4&times;4 </td><td style="text-align:left"> Matrix that converts from clip (NDC) space to world space </td></tr>
</table></div>
</p>
@@ -2501,7 +2504,7 @@ a good compromise between runtime performance and size.</p>
metadata in JSON format. The example below prints out the list of parameters defined in Filament's
standard skybox material. It produces a list of 2 parameters, named <code>showSun</code> and <code>skybox</code>,
respectively a boolean and a cubemap texture.</p>
</p><pre class="listing backtick"><code><span class="line"></span>$ matc --reflect parameters filament/src/materials/skybox.mat
</p><pre class="listing backtick"><code><span class="line"></span>$ matc --reflect parameters filament/src/materials/skybox.mat
<span class="line"></span>{
<span class="line"></span> &quot;parameters&quot;: [
<span class="line"></span> {
@@ -2600,7 +2603,7 @@ Finally if <code>variantFilter</code> contains the <code>fog</code> filter, an e
</p><p>
Be aware that <code>external</code> samplers account for 2 regular samplers.</div>
</p><p>
</p></span><div id="mdContextMenu" style="visibility:hidden"></div><div class="markdeepFooter"><i>formatted by <a href="https://casual-effects.com/markdeep" style="color:#999">Markdeep&nbsp;1.18&nbsp;&nbsp;</a></i><div style="display:inline-block;font-size:13px;font-family:'Times New Roman',serif;vertical-align:middle;transform:translate(-3px,-1px)rotate(135deg);">&#x2712;</div></div><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.6/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</p></span><div id="mdContextMenu" style="visibility:hidden"></div><div class="markdeepFooter"><i>formatted by <a href="https://casual-effects.com/markdeep" style="color:#999">Markdeep&nbsp;1.18&nbsp;&nbsp;</a></i><div style="display:inline-block;font-size:13px;font-family:'Times New Roman',serif;vertical-align:middle;transform:translate(-3px,-1px)rotate(135deg);">&#x2712;</div></div><script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
+2 -2
View File
@@ -250,7 +250,7 @@ execution profile data.</p>
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../notes/framegraph.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../notes/performance_analysis.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
@@ -264,7 +264,7 @@ execution profile data.</p>
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../notes/framegraph.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../notes/performance_analysis.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
+4 -4
View File
@@ -331,11 +331,11 @@ nodes</li>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../notes/coverage.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../notes/performance_analysis.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../notes/libs.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../notes/tests.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
@@ -345,11 +345,11 @@ nodes</li>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../notes/coverage.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../notes/performance_analysis.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../notes/libs.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../notes/tests.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
+2 -2
View File
@@ -165,7 +165,7 @@
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../notes/framegraph.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/renderdiff.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
@@ -179,7 +179,7 @@
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../notes/framegraph.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/renderdiff.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
+352
View File
@@ -0,0 +1,352 @@
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Performance analysis - Filament</title>
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<!-- Provide site root to javascript -->
<script>
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
</script>
<!-- Start loading toc.js asap -->
<script src="../toc.js"></script>
</head>
<body>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('light')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div style="display:flex;align-items:center;justify-content:center">
<img class="flogo" src="../images/filament_logo_small.png"></img>
</div>
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
</noscript>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<!-- Filament: disable themes because the markdeep part does not look good for dark themes -->
<!--
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
-->
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Filament</h1>
<div class="right-buttons">
<a href="https://github.com/google/filament" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="performance-analysis"><a class="header" href="#performance-analysis">Performance Analysis</a></h1>
<h2 id="android"><a class="header" href="#android">Android</a></h2>
<h3 id="prerequisites"><a class="header" href="#prerequisites">Prerequisites</a></h3>
<ul>
<li>Download and install Android GPU Inspector (AGI). See https://developer.android.com/agi.</li>
</ul>
<hr />
<h4 id="profiling"><a class="header" href="#profiling">Profiling</a></h4>
<ol>
<li>
<p>Before profiling the application or analyzing the performance in a consistent way, ideally
the <strong>GPU frequency on the target hardware should get locked</strong>. In order to do this, you need to do the following:</p>
<ol>
<li>Ensure your device is OEM unlocked. If your phone is carrier-locked, you may need
to wait a period, such as 60 or 90 days after activation to be eligible for unlocking.
Some phones don't support this at all. You will need to enable developer options
(e.g. Settings &gt; About Phone and tap the Build number 7 times). You need to go to
Settings &gt; System &gt; Developer options and toggle on "OEM unlocking".</li>
<li>Next, you need to unlock the phone. You will need to install Android SDK Platform
Tools on you computer, enable "USB debugging" in your phone's Settings &gt; System &gt; Developer options.</li>
<li>Connect the phone to the computer via a USB cable and run from the command line:
<pre><code class="language-shell">adb reboot bootloader
# once the phone is in bootloader mode, run the following to begin the unlocking
# process:
fastboot flashing unlock
</code></pre>
A warning will appear on your phone's screen. Use the volume buttons to navigate and
the power button to select the "Unlock the bootloader" option. The phone will perform
a factory data reset and reboot with an unlocked bootloader.</li>
<li>You would need to flash an image to the phone with root permissions, such as a *-userdebug or *-eng
build. One way to do this is with the <a href="https://flash.android.com/">Android Flash Tool</a>. Connect the
tool to your device and find a build to flash ending in <code>-userdebug</code> or <code>-eng</code>. Once you have that
selected run <code>Install build</code>.</li>
<li>Shell into your device as root and configure the gpu frequency to be locked, e.g.:
<pre><code class="language-shell">adb shell
su
# navigate to the system GPU directory. this varies on different phones. One phone might have
# it at /sys/class/kgsl/kgsl-3d0 and another might be in something similar, maybe with "mali" instead
# of "kgsl". At the time of writing this for the device at hand it was /sys/devices/platform/1f000000.mali
cd /sys/devices/platform/1f000000.mali
# get the current available GPU governors and frequencies.
# note that some systems may have these at gpu_available_governors and gpu_available_frequencies, but
# the system at the time of writing this had available_governors and available_frequences
cat available_governors
cat available_frequencies
# depending on the governors, you may want to set it prioritize performance over other things like
# battery. Some systems allow you to do this with something like (although, for the device used at the
# time of writing this did not have an equivalent option):
echo performance &gt; gpu_governor
# finally, lock your frequency in, usually to something high like 897 MHz. Some systems may have you
# pipe the value to gpu_min_freq and gpu_max_freq, but the system used at the time of writing this had:
echo 940000 &gt; hint_min_freq
echo 940000 &gt; hint_max_freq
# you can typically verify the GPU is running at that frequency consistently by running something like
# the following a few times over time, which should show the frequency you want to lock the device to:
cat cur_freq
</code></pre>
</li>
<li>You may need to re-apply the <code>hint_min_freq</code> just before starting the profiling trace and check before and after
that the frequency remained at the value expected. Some systems may adjust the frequency on you, but you
may want to ensure the frequency remains the same through the analysis.</li>
<li>The GPU frequency settings should be undone after restarting the device, but after you have done your app profiling,
you can revert the state of the device, such as the OS build image, back to the way you had it
initially, as needed.</li>
</ol>
</li>
<li>
<p>Build a release build of Filament with the applicable backend(s) enabled
<em>(+ any special flags for enabling sys strace. Nothing special is needed for Vulkan or WebGPU aside from
building a release build with no flags)</em> <em>(debug builds for this are useless)</em></p>
<pre><code class="language-shell"># the following command assumes you are in the root filament directory
# and ANDROID_HOME is exported (and possibly also CC and CXX on linux as needed)
#
# NOTE: to build with WebGPU support you need to explicitly include the -W flag
# (it doesn't get compiled in by default), e.g.:
# ./build.sh -W -p android,desktop -i release
#
# Note that you can speed this up a bit (and reduce disk space usage) by limiting the target to just
# the ABI you plan on testing with the -q flag, e.g. -q arm64-v8a. If you do this, you
# will need to update the android/gradle.properties file to specify the ABI(s) you are targeting
# with the com.google.android.filament.abis property.
# Thus, a build command that would target BOTH Vulkan AND WebGPU AND only target the ARM64 ABI would look something
# like:
# ./build.sh -W -q arm64-v8a -p android,desktop -i release
./build.sh -p android,desktop -i release
</code></pre>
</li>
<li>
<p>Connect your Android device to your computer via a USB cord with USB debugging enabled and configure
the system property to default to the desired backend, e.g.
<em>(to determine how these numbers map to the backends, see the <code>enum class Backend</code>
definition in <a href="../../../../filament/backend/include/backend/DriverEnums.h">filament/filament/backend/include/backend/DriverEnums.h</a>)</em>:</p>
<pre><code class="language-shell"># to set the backend to Vulkan:
adb shell setprop debug.filament.backend 2
# to set the backend to WebGPU:
adb shell setprop debug.filament.backend 4
# to view the current property:
adb shell getprop debug.filament.backend
</code></pre>
</li>
<li>
<p>Build and run a sample, e.g. sample-gltf-viewer, on your Android device
<em>(<a href="https://developer.android.com/studio">Android Studio</a> recommended)</em>.</p>
</li>
<li>
<p>Run <a href="https://developer.android.com/agi">AGI</a> and follow instructions to profile the app/system
with trace capture(s). See https://developer.android.com/agi/start for more details to
get started.</p>
<ul>
<li>We typically only run "Capture System Profiler trace" <em>(not necessarily "Capture Frame Profiler trace")</em></li>
<li>When configuring the trace:
<ul>
<li>For both the WebGPU and Vulkan backends configure the profiler for the Vulkan API
<em>(since WebGPU should be using Vulkan under the hood as well)</em></li>
<li>Running for ~1 seconds should suffice</li>
<li>Hit the "Configure" button in Trace objects, select "Switch to advanced mode" and add:
<pre><code>data_sources {
config {
name: "track_event"
track_event_config {
disabled_categories: "*"
enabled_categories: "filament/filament"
enabled_categories: "filament/jobsystem"
enabled_categories: "filament/gltfio"
}
}
}
</code></pre>
</li>
</ul>
</li>
<li>One you open the trace, zoom into a series of frames to get a sense of generally how long they typically take
<em>(use <code>W</code>, <code>S</code>, <code>A</code> and <code>D</code> keys and mouse wheel for navigation)</em> and find a representative one.
We are most interested in the performance of the
<code>FEngine::loop</code> thread, how long it takes, overlap in activities/processes/commands, reduction in queue submissions,
etc. Similarly, we can view GPU timeline as it relates to that. We want to see overlapping
shader invocations and non-interrupted fragment shader runs.</li>
</ul>
</li>
</ol>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../notes/coverage.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../notes/framegraph.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../notes/coverage.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../notes/framegraph.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js"></script>
<script src="../mark.min.js"></script>
<script src="../searcher.js"></script>
<script src="../clipboard.min.js"></script>
<script src="../highlight.js"></script>
<script src="../book.js"></script>
<!-- Custom JS scripts -->
</div>
</body>
</html>
+215
View File
@@ -0,0 +1,215 @@
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Tests - Filament</title>
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<!-- Provide site root to javascript -->
<script>
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
</script>
<!-- Start loading toc.js asap -->
<script src="../toc.js"></script>
</head>
<body>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('light')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div style="display:flex;align-items:center;justify-content:center">
<img class="flogo" src="../images/filament_logo_small.png"></img>
</div>
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
</noscript>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<!-- Filament: disable themes because the markdeep part does not look good for dark themes -->
<!--
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
-->
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Filament</h1>
<div class="right-buttons">
<a href="https://github.com/google/filament" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="tests"><a class="header" href="#tests">Tests</a></h1>
<p>Filament has a collection of tests that can be run locally. Many of them are used
for in our Continuation Integration flow <a href="https://https://github.com/google/filament/tree/main/.github/workflows">on github</a>.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../notes/framegraph.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/renderdiff.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../notes/framegraph.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/renderdiff.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js"></script>
<script src="../mark.min.js"></script>
<script src="../searcher.js"></script>
<script src="../clipboard.min.js"></script>
<script src="../highlight.js"></script>
<script src="../book.js"></script>
<!-- Custom JS scripts -->
</div>
</body>
</html>
File diff suppressed because one or more lines are too long
Binary file not shown.
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+6
View File
@@ -78,5 +78,11 @@
},
"docs_src/README.md": {
"dest": "dup/docs.md"
},
"test/renderdiff/README.md": {
"dest": "dup/renderdiff.md",
"link_transforms": {
"docs/images/": "../images/"
}
}
}
+25 -22
View File
@@ -212,7 +212,7 @@ when using textures.
This property can dramatically change the appearance of a surface. Non-metallic surfaces have
chromatic diffuse reflection and achromatic specular reflection (reflected light does not change
color). Metallic surfaces do not have any diffuse reflection and chromatic specular reflection
(reflected light takes on the color of the surfaced as defined by `baseColor`).
(reflected light takes on the color of the surfaced as defined by `baseColor`).
The effect of `metallic` is shown in figure [metallicProperty] (click on the image to see a
larger version).
@@ -248,7 +248,7 @@ The effect of `roughness` on metallic surfaces is shown in figure [roughnessCond
When refraction through an object is enabled (using a `refractonType` of `thin` or `solid`), the
`roughness` property will also affect the refractions, as shown in figure
[roughnessRefractionProperty] (click on the image to see a larger version).
![Figure [roughnessRefractionProperty]: Refractive sphere with `roughness` varying from 0.0
(left) to 1.0 (right)](images/materials/refraction_roughness.png)
@@ -307,7 +307,7 @@ The sheen color controls the color appearance and strength of an optional sheen
base layer described by the properties above. The sheen layer always sits below the clear coat layer
if such a layer is present.
The sheen layer can be used to represent cloth and fabric materials. Please refer to
The sheen layer can be used to represent cloth and fabric materials. Please refer to
section [Cloth model] for more information about cloth and fabric materials.
The effect of `sheenColor` is shown in figure [materialSheenColor]
@@ -520,14 +520,14 @@ light to bend further away from the initial path.
Table [commonMatIOR] describes acceptable refractive indices for various types of materials.
Material | IOR
Material | IOR
--------------------------:|:-----------------
Air | 1.0
Water | 1.33
Common liquids | 1.33 to 1.5
Common gemstones | 1.58 to 2.33
Plastics, glass | 1.5 to 1.58
Other dielectric materials | 1.33 to 1.58
Water | 1.33
Common liquids | 1.33 to 1.5
Common gemstones | 1.58 to 2.33
Plastics, glass | 1.5 to 1.58
Other dielectric materials | 1.33 to 1.58
[Table [commonMatIOR]: Index of refraction of common materials]
The appearance of a refractive material will greatly depend on the `refractionType` and
@@ -995,10 +995,10 @@ Value
name must be a valid GLSL identifier. Entries have an optional `precision`, which can be
one of `default` (best precision for the platform, typically `high` on desktop, `medium` on
mobile), `low`, `medium`, `high`. The type must be one of the types described in
table [materialParamsTypes]. For Android external textures, entries also have an optional
transformName parameter to specify the name of the material parameter that will be
table [materialParamsTypes]. For Android external textures, entries also have an optional
transformName parameter to specify the name of the material parameter that will be
used to expose the transform matrix associated with the external sampler. In iOS and Vulkan,
this will always be identity.
this will always be identity.
Type | Description
:----------------------|:---------------------------------
@@ -2476,14 +2476,17 @@ type aliases:
### Matrices
Name | Type | Description
:-----------------------------------|:--------:|:------------------------------------
**getViewFromWorldMatrix()** | float4x4 | Matrix that converts from world space to view/eye space
**getWorldFromViewMatrix()** | float4x4 | Matrix that converts from view/eye space to world space
**getClipFromViewMatrix()** | float4x4 | Matrix that converts from view/eye space to clip (NDC) space
**getViewFromClipMatrix()** | float4x4 | Matrix that converts from clip (NDC) space to view/eye space
**getClipFromWorldMatrix()** | float4x4 | Matrix that converts from world to clip (NDC) space
**getWorldFromClipMatrix()** | float4x4 | Matrix that converts from clip (NDC) space to world space
Name | Type | Description
:-----------------------------------------|:--------:|:------------------------------------
**getViewFromWorldMatrix()** | float4x4 | Matrix that converts from world space to view/eye space
**getWorldFromViewMatrix()** | float4x4 | Matrix that converts from view/eye space to world space
**getClipFromViewMatrix()** | float4x4 | Matrix that converts from view/eye space to clip (NDC) space
**getViewFromClipMatrix()** | float4x4 | Matrix that converts from clip (NDC) space to view/eye space
**getEyeFromViewMatrix()** | float4x4 | Matrix that converts from view space to eye space
**getEyeFromViewMatrix(int eyeIndex)** | float4x4 | Matrix that converts from view space to eye space for the eye referred to by eyeIndex
**getClipFromWorldMatrix()** | float4x4 | Matrix that converts from world to clip (NDC) space
**getClipFromWorldMatrix(int eyeIndex)** | float4x4 | Matrix that converts from world to clip (NDC) space for the eye referred to by eyeIndex
**getWorldFromClipMatrix()** | float4x4 | Matrix that converts from clip (NDC) space to world space
### Frame constants
@@ -2639,7 +2642,7 @@ standard skybox material. It produces a list of 2 parameters, named `showSun` an
respectively a boolean and a cubemap texture.
```text
$ matc --reflect parameters filament/src/materials/skybox.mat
$ matc --reflect parameters filament/src/materials/skybox.mat
{
"parameters": [
{
@@ -2655,7 +2658,7 @@ $ matc --reflect parameters filament/src/materials/skybox.mat
}
]
}
```
```
### --variant-filter
+4
View File
@@ -3,6 +3,7 @@
- [Introduction](./dup/intro.md)
- [Build](./dup/building.md)
- [Build for Android on Windows](./build/windows_android.md)
- [Maven Release](./build/maven_release.md)
- [Contribute](./dup/contributing.md)
- [Coding Style](./dup/code_style.md)
- [Core Concepts](./main/README.md)
@@ -24,7 +25,10 @@
- [Running with ASAN and UBSAN](./notes/asan_ubsan.md)
- [Using Instruments on macOS](./notes/instruments.md)
- [Code coverage analysis](./notes/coverage.md)
- [Performance analysis](./notes/performance_analysis.md)
- [Framegraph](./notes/framegraph.md)
- [Tests](./notes/tests.md)
- [renderdiff](./dup/renderdiff.md)
- [Libraries](./notes/libs.md)
- [bluegl](./dup/bluegl.md)
- [bluevk](./dup/bluevk.md)
@@ -0,0 +1,89 @@
# Maven Release
## Register for a Sonatype Account
First, you'll need to register for a Sonatype account at the [Central
Portal](https://central.sonatype.org/register/central-portal/).
To publish under the `com.google.android` namespace, you'll also need to email
`central-support@sonatype.com` with your account information to request access.
Then, generate a user token through the Sonatype website. Navigate to
[https://central.sonatype.com/account](https://central.sonatype.com/account) and select **Generate
User Token**.
Finally, add the generated token credentials to `~/.gradle/gradle.properties`. (Note: these are
different from the credentials used to log into your Sonatype account):
```gradle
# Generated Sonatype token
sonatypeUsername=<username>
sonatypePassword=<password>
```
-----
## Signing Key
All release artifacts must be signed. You'll need to create an OpenPGP key pair. See Gradle's
documentation on [Signatory
credentials](https://docs.gradle.org/current/userguide/signing_plugin.html#sec:signatory_credentials)
for instructions.
Update `~/.gradle/gradle.properties` with your new key's credentials:
```gradle
signing.keyId=<key id>
signing.password=<key password>
signing.secretKeyRingFile=<secret key ring file>
```
-----
## Build the Android Release
Make sure `JAVA_HOME` is set correctly. For example:
```bash
export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home
./build.sh -C -i -p android release
```
-----
## Publish to Sonatype
### A Note on the Legacy Staging Service
Previously, Filament was published to Maven via OSSRH (Open Source Software Repository Hosting). In
2025, this service was [sunsetted](https://central.sonatype.org/pages/ossrh-eol/). Now, we use
Sonatype's [Central Publisher Portal](https://central.sonatype.org/).
The new Central Publisher Portal does not officially support Gradle. However, Sonatype provides a
staging API compatibility service, which works with Filament's Gradle setup.
-----
### 1\. Upload to the Staging API Compatibility Service
```bash
cd android
./gradlew publishToSonatype
```
### 2\. Move the Repository to the Central Publisher Portal
We have a script to automate this. It reads the `sonatypeUsername` and `sonatypePassword` from your
`~/.gradle/gradle.properties` file.
```bash
python3 build/common/close-sonatype-staging-repository.py
```
### 3\. Publish the Release on Sonatype
Navigate to [Maven Central Repository Deployments](https://central.sonatype.com/publishing/deployments).
Here, you should see a new deployment with a **Validated** status and all your artifacts listed. Click
the **Publish** button to publish the artifacts. It typically takes around 5 minutes after clicking
**Publish** for the artifacts to go live.
Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

@@ -0,0 +1,129 @@
# Performance Analysis
## Android
### Prerequisites
- Download and install Android GPU Inspector (AGI). See https://developer.android.com/agi.
---
#### Profiling
1. Before profiling the application or analyzing the performance in a consistent way, ideally
the **GPU frequency on the target hardware should get locked**. In order to do this, you need to do the following:
1. Ensure your device is OEM unlocked. If your phone is carrier-locked, you may need
to wait a period, such as 60 or 90 days after activation to be eligible for unlocking.
Some phones don't support this at all. You will need to enable developer options
(e.g. Settings > About Phone and tap the Build number 7 times). You need to go to
Settings > System > Developer options and toggle on "OEM unlocking".
1. Next, you need to unlock the phone. You will need to install Android SDK Platform
Tools on you computer, enable "USB debugging" in your phone's Settings > System > Developer options.
1. Connect the phone to the computer via a USB cable and run from the command line:
```shell
adb reboot bootloader
# once the phone is in bootloader mode, run the following to begin the unlocking
# process:
fastboot flashing unlock
```
A warning will appear on your phone's screen. Use the volume buttons to navigate and
the power button to select the "Unlock the bootloader" option. The phone will perform
a factory data reset and reboot with an unlocked bootloader.
1. You would need to flash an image to the phone with root permissions, such as a *-userdebug or *-eng
build. One way to do this is with the [Android Flash Tool](https://flash.android.com/). Connect the
tool to your device and find a build to flash ending in `-userdebug` or `-eng`. Once you have that
selected run `Install build`.
1. Shell into your device as root and configure the gpu frequency to be locked, e.g.:
```shell
adb shell
su
# navigate to the system GPU directory. this varies on different phones. One phone might have
# it at /sys/class/kgsl/kgsl-3d0 and another might be in something similar, maybe with "mali" instead
# of "kgsl". At the time of writing this for the device at hand it was /sys/devices/platform/1f000000.mali
cd /sys/devices/platform/1f000000.mali
# get the current available GPU governors and frequencies.
# note that some systems may have these at gpu_available_governors and gpu_available_frequencies, but
# the system at the time of writing this had available_governors and available_frequences
cat available_governors
cat available_frequencies
# depending on the governors, you may want to set it prioritize performance over other things like
# battery. Some systems allow you to do this with something like (although, for the device used at the
# time of writing this did not have an equivalent option):
echo performance > gpu_governor
# finally, lock your frequency in, usually to something high like 897 MHz. Some systems may have you
# pipe the value to gpu_min_freq and gpu_max_freq, but the system used at the time of writing this had:
echo 940000 > hint_min_freq
echo 940000 > hint_max_freq
# you can typically verify the GPU is running at that frequency consistently by running something like
# the following a few times over time, which should show the frequency you want to lock the device to:
cat cur_freq
```
1. You may need to re-apply the `hint_min_freq` just before starting the profiling trace and check before and after
that the frequency remained at the value expected. Some systems may adjust the frequency on you, but you
may want to ensure the frequency remains the same through the analysis.
1. The GPU frequency settings should be undone after restarting the device, but after you have done your app profiling,
you can revert the state of the device, such as the OS build image, back to the way you had it
initially, as needed.
1. Build a release build of Filament with the applicable backend(s) enabled
_(+ any special flags for enabling sys strace. Nothing special is needed for Vulkan or WebGPU aside from
building a release build with no flags)_ _(debug builds for this are useless)_
```shell
# the following command assumes you are in the root filament directory
# and ANDROID_HOME is exported (and possibly also CC and CXX on linux as needed)
#
# NOTE: to build with WebGPU support you need to explicitly include the -W flag
# (it doesn't get compiled in by default), e.g.:
# ./build.sh -W -p android,desktop -i release
#
# Note that you can speed this up a bit (and reduce disk space usage) by limiting the target to just
# the ABI you plan on testing with the -q flag, e.g. -q arm64-v8a. If you do this, you
# will need to update the android/gradle.properties file to specify the ABI(s) you are targeting
# with the com.google.android.filament.abis property.
# Thus, a build command that would target BOTH Vulkan AND WebGPU AND only target the ARM64 ABI would look something
# like:
# ./build.sh -W -q arm64-v8a -p android,desktop -i release
./build.sh -p android,desktop -i release
```
1. Connect your Android device to your computer via a USB cord with USB debugging enabled and configure
the system property to default to the desired backend, e.g.
_(to determine how these numbers map to the backends, see the `enum class Backend`
definition in [filament/filament/backend/include/backend/DriverEnums.h](../../../../filament/backend/include/backend/DriverEnums.h))_:
```shell
# to set the backend to Vulkan:
adb shell setprop debug.filament.backend 2
# to set the backend to WebGPU:
adb shell setprop debug.filament.backend 4
# to view the current property:
adb shell getprop debug.filament.backend
```
1. Build and run a sample, e.g. sample-gltf-viewer, on your Android device
_([Android Studio](https://developer.android.com/studio) recommended)_.
1. Run [AGI](https://developer.android.com/agi) and follow instructions to profile the app/system
with trace capture(s). See https://developer.android.com/agi/start for more details to
get started.
- We typically only run "Capture System Profiler trace" _(not necessarily "Capture Frame Profiler trace")_
- When configuring the trace:
- For both the WebGPU and Vulkan backends configure the profiler for the Vulkan API
_(since WebGPU should be using Vulkan under the hood as well)_
- Running for ~1 seconds should suffice
- Hit the "Configure" button in Trace objects, select "Switch to advanced mode" and add:
```
data_sources {
config {
name: "track_event"
track_event_config {
disabled_categories: "*"
enabled_categories: "filament/filament"
enabled_categories: "filament/jobsystem"
enabled_categories: "filament/gltfio"
}
}
}
```
- One you open the trace, zoom into a series of frames to get a sense of generally how long they typically take
_(use `W`, `S`, `A` and `D` keys and mouse wheel for navigation)_ and find a representative one.
We are most interested in the performance of the
`FEngine::loop` thread, how long it takes, overlap in activities/processes/commands, reduction in queue submissions,
etc. Similarly, we can view GPU timeline as it relates to that. We want to see overlapping
shader invocations and non-interrupted fragment shader runs.
+4
View File
@@ -0,0 +1,4 @@
# Tests
Filament has a collection of tests that can be run locally. Many of them are used
for in our Continuation Integration flow [on github](https://https://github.com/google/filament/tree/main/.github/workflows).
File diff suppressed because one or more lines are too long
Binary file not shown.
+11 -1
View File
@@ -40,6 +40,7 @@ set(PUBLIC_HDRS
include/filament/Skybox.h
include/filament/Stream.h
include/filament/SwapChain.h
include/filament/Sync.h
include/filament/Texture.h
include/filament/TextureSampler.h
include/filament/ToneMapper.h
@@ -83,6 +84,8 @@ set(SRCS
src/InstanceBuffer.cpp
src/LightManager.cpp
src/Material.cpp
src/MaterialCache.cpp
src/MaterialDefinition.cpp
src/MaterialInstance.cpp
src/MaterialInstanceManager.cpp
src/MaterialParser.cpp
@@ -103,6 +106,7 @@ set(SRCS
src/Skybox.cpp
src/Stream.cpp
src/SwapChain.cpp
src/Sync.cpp
src/Texture.cpp
src/ToneMapper.cpp
src/TransformManager.cpp
@@ -113,6 +117,7 @@ set(SRCS
src/components/LightManager.cpp
src/components/RenderableManager.cpp
src/components/TransformManager.cpp
src/details/BufferAllocator.cpp
src/details/BufferObject.cpp
src/details/Camera.cpp
src/details/ColorGrading.cpp
@@ -132,6 +137,7 @@ set(SRCS
src/details/Skybox.cpp
src/details/Stream.cpp
src/details/SwapChain.cpp
src/details/Sync.cpp
src/details/Texture.cpp
src/details/VertexBuffer.cpp
src/details/View.cpp
@@ -172,6 +178,8 @@ set(PRIVATE_HDRS
src/HwRenderPrimitiveFactory.h
src/HwVertexBufferInfoFactory.h
src/Intersections.h
src/MaterialCache.h
src/MaterialDefinition.h
src/MaterialParser.h
src/MaterialInstanceManager.h
src/PIDController.h
@@ -189,6 +197,7 @@ set(PRIVATE_HDRS
src/components/LightManager.h
src/components/RenderableManager.h
src/components/TransformManager.h
src/details/BufferAllocator.h
src/details/BufferObject.h
src/details/Camera.h
src/details/ColorGrading.h
@@ -242,9 +251,10 @@ set(PRIVATE_HDRS
set(MATERIAL_SRCS
src/materials/antiAliasing/fxaa/fxaa.mat
src/materials/antiAliasing/taa/taa.mat
src/materials/blitArray.mat
src/materials/blitDepth.mat
src/materials/blitLow.mat
src/materials/blitArray.mat
src/materials/clearDepth.mat
src/materials/bloom/bloomDownsample.mat
src/materials/bloom/bloomDownsample2x.mat
src/materials/bloom/bloomDownsample9.mat
+22 -5
View File
@@ -78,6 +78,8 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3)
src/opengl/GLTexture.h
src/opengl/GLUtils.cpp
src/opengl/GLUtils.h
src/opengl/GLMemoryMappedBuffer.cpp
src/opengl/GLMemoryMappedBuffer.h
src/opengl/OpenGLBlobCache.cpp
src/opengl/OpenGLBlobCache.h
src/opengl/OpenGLContext.cpp
@@ -177,6 +179,7 @@ endif()
if (FILAMENT_SUPPORTS_VULKAN)
list(APPEND SRCS
include/backend/platforms/VulkanPlatform.h
src/vulkan/VulkanAsyncHandles.cpp
src/vulkan/VulkanAsyncHandles.h
src/vulkan/VulkanBlitter.cpp
src/vulkan/VulkanBlitter.h
@@ -215,6 +218,10 @@ if (FILAMENT_SUPPORTS_VULKAN)
src/vulkan/VulkanReadPixels.h
src/vulkan/VulkanSamplerCache.cpp
src/vulkan/VulkanSamplerCache.h
src/vulkan/VulkanSemaphore.cpp
src/vulkan/VulkanSemaphore.h
src/vulkan/VulkanSemaphoreManager.cpp
src/vulkan/VulkanSemaphoreManager.h
src/vulkan/VulkanStagePool.cpp
src/vulkan/VulkanStagePool.h
src/vulkan/VulkanSwapChain.cpp
@@ -287,6 +294,8 @@ if (FILAMENT_SUPPORTS_WEBGPU)
src/webgpu/WebGPUPipelineLayoutCache.h
src/webgpu/WebGPUProgram.cpp
src/webgpu/WebGPUProgram.h
src/webgpu/WebGPUQueueManager.cpp
src/webgpu/WebGPUQueueManager.h
src/webgpu/WebGPURenderPassMipmapGenerator.cpp
src/webgpu/WebGPURenderPassMipmapGenerator.h
src/webgpu/WebGPURenderPrimitive.h
@@ -295,6 +304,7 @@ if (FILAMENT_SUPPORTS_WEBGPU)
src/webgpu/WebGPUStrings.h
src/webgpu/WebGPUSwapChain.cpp
src/webgpu/WebGPUSwapChain.h
src/webgpu/WebGPUSync.h
src/webgpu/WebGPUTexture.cpp
src/webgpu/WebGPUTexture.h
src/webgpu/WebGPUTextureHelpers.h
@@ -494,9 +504,6 @@ else()
-Wover-aligned -Wreorder-init-list
-Werror
)
if (CMAKE_CXX_STANDARD EQUAL 20)
list(APPEND FILAMENT_WARNINGS -Wno-deprecated-this-capture)
endif()
endif()
if (APPLE)
@@ -530,7 +537,7 @@ target_link_libraries(${TARGET} PRIVATE
if (LINUX AND FILAMENT_SUPPORTS_WEBGPU)
# Unclear why this needs to be explicit while other linux libs do not, but it is necessary for
# WebGPU to build on linux.
target_link_libraries(${TARGET} PRIVATE -lxcb)
target_link_libraries(${TARGET} PRIVATE -lxcb -lX11)
endif()
# ==================================================================================================
@@ -568,6 +575,7 @@ if (APPLE OR LINUX)
test/test_ReadPixels.cpp
test/test_BufferUpdates.cpp
test/test_Callbacks.cpp
test/test_MemoryMappedBuffer.cpp
test/test_MRT.cpp
test/test_PushConstants.cpp
test/test_LoadImage.cpp
@@ -580,7 +588,9 @@ if (APPLE OR LINUX)
test/test_Template.cpp
)
if (FILAMENT_SUPPORTS_WEBGPU)
list(APPEND BACKEND_TEST_SRC test/test_WebGPUAsyncTaskCounter.cpp)
list(APPEND BACKEND_TEST_SRC
test/test_WebGPUAsyncTaskCounter.cpp
test/test_WebGPUComposeSwizzle.cpp)
endif()
if (APPLE)
# Metal-specific tests
@@ -629,6 +639,10 @@ if (APPLE AND NOT IOS)
target_link_libraries(backend_test PRIVATE image imageio)
list(APPEND BACKEND_TEST_DEPS image)
endif()
if (FILAMENT_SUPPORTS_WEBGPU)
target_link_libraries(backend_test PRIVATE webgpu_dawn dawncpp_headers)
list(APPEND BACKEND_TEST_DEPS webgpu_dawn dawncpp_headers)
endif()
set(BACKEND_TEST_COMBINED_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libbackendtest_combined.a")
combine_static_libs(backend_test "${BACKEND_TEST_COMBINED_OUTPUT}" "${BACKEND_TEST_DEPS}")
@@ -660,6 +674,9 @@ if (LINUX)
add_executable(backend_test_linux test/linux_runner.cpp ${BACKEND_TEST_SRC})
target_link_libraries(backend_test_linux PRIVATE ${BACKEND_TEST_LIBS})
set_target_properties(backend_test_linux PROPERTIES FOLDER Tests)
if (FILAMENT_SUPPORTS_WEBGPU)
target_link_libraries(backend_test_linux PRIVATE webgpu_dawn dawncpp_headers)
endif()
endif()
# ==================================================================================================
+60 -4
View File
@@ -101,6 +101,16 @@ static constexpr uint64_t SWAP_CHAIN_HAS_STENCIL_BUFFER = SWAP_CHAIN_CON
*/
static constexpr uint64_t SWAP_CHAIN_CONFIG_PROTECTED_CONTENT = 0x40;
/**
* Indicates that the SwapChain is configured to use Multi-Sample Anti-Aliasing (MSAA) with the
* given sample points within each pixel. Only supported when isMSAASwapChainSupported(4) is
* true.
*
* This is only supported by EGL(Android). Other GL platforms (GLX, WGL, etc) don't support it
* because the swapchain MSAA settings must be configured before window creation.
*/
static constexpr uint64_t SWAP_CHAIN_CONFIG_MSAA_4_SAMPLES = 0x80;
static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_SAMPLER_COUNT = 62; // Maximum needed at feature level 3.
static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects.
@@ -187,6 +197,7 @@ constexpr std::string_view to_string(Backend const backend) noexcept {
* - The Metal backend can prefer precompiled Metal libraries, while falling back to MSL.
*/
enum class ShaderLanguage {
UNSPECIFIED = -1,
ESSL1 = 0,
ESSL3 = 1,
SPIRV = 2,
@@ -209,6 +220,8 @@ constexpr const char* shaderLanguageToString(ShaderLanguage shaderLanguage) noex
return "Metal precompiled library";
case ShaderLanguage::WGSL:
return "WGSL";
case ShaderLanguage::UNSPECIFIED:
return "Unspecified";
}
return "UNKNOWN";
}
@@ -546,12 +559,21 @@ constexpr TargetBufferFlags getTargetBufferFlagsAt(size_t index) noexcept {
}
/**
* Frequency at which a buffer is expected to be modified and used. This is used as an hint
* for the driver to make better decisions about managing memory internally.
* How the buffer will be used.
*/
enum class BufferUsage : uint8_t {
STATIC, //!< content modified once, used many times
DYNAMIC, //!< content modified frequently, used many times
STATIC = 0, //!< (legacy) content modified once, used many times
DYNAMIC = 1, //!< (legacy) content modified frequently, used many times
DYNAMIC_BIT = 0x1, //!< buffer can be modified frequently, used many times
SHARED_WRITE_BIT = 0x04, //!< buffer can be memory mapped for write operations
};
/**
* How the buffer will be mapped.
*/
enum class MapBufferAccessFlags : uint8_t {
WRITE_BIT = 0x2, //!< buffer is mapped from writing
INVALIDATE_RANGE_BIT = 0x4, //!< the mapped range content is lost
};
/**
@@ -617,6 +639,15 @@ enum class ShaderModel : uint8_t {
};
static constexpr size_t SHADER_MODEL_COUNT = 2;
constexpr std::string_view to_string(ShaderModel model) noexcept {
switch (model) {
case ShaderModel::MOBILE:
return "mobile";
case ShaderModel::DESKTOP:
return "desktop";
}
}
/**
* Primitive types
*/
@@ -629,6 +660,18 @@ enum class PrimitiveType : uint8_t {
TRIANGLE_STRIP = 5 //!< triangle strip
};
[[nodiscard]] constexpr bool isStripPrimitiveType(const PrimitiveType type) {
switch (type) {
case PrimitiveType::POINTS:
case PrimitiveType::LINES:
case PrimitiveType::TRIANGLES:
return false;
case PrimitiveType::LINE_STRIP:
case PrimitiveType::TRIANGLE_STRIP:
return true;
}
}
/**
* Supported uniform types
*/
@@ -670,6 +713,12 @@ enum class Precision : uint8_t {
DEFAULT
};
union ConstantValue {
int32_t i;
float f;
bool b;
};
/**
* Shader compiler priority queue
*
@@ -1654,6 +1703,8 @@ enum class Workaround : uint16_t {
// prevents these stutters by not precaching depth variants of the default material for those
// particular browsers.
DISABLE_DEPTH_PRECACHE_FOR_DEFAULT_MATERIAL,
// Emulate an sRGB swapchain in shader code.
EMULATE_SRGB_SWAPCHAIN,
};
using StereoscopicType = backend::Platform::StereoscopicType;
@@ -1670,6 +1721,11 @@ template<> struct utils::EnableBitMaskOperators<filament::backend::TextureUsage>
: public std::true_type {};
template<> struct utils::EnableBitMaskOperators<filament::backend::StencilFace>
: public std::true_type {};
template<> struct utils::EnableBitMaskOperators<filament::backend::BufferUsage>
: public std::true_type {};
template<> struct utils::EnableBitMaskOperators<filament::backend::MapBufferAccessFlags>
: public std::true_type {};
template<> struct utils::EnableIntegerOperators<filament::backend::TextureCubemapFace>
: public std::true_type {};
template<> struct utils::EnableIntegerOperators<filament::backend::FeatureLevel>
@@ -38,12 +38,14 @@ struct HwRenderPrimitive;
struct HwRenderTarget;
struct HwStream;
struct HwSwapChain;
struct HwSync;
struct HwTexture;
struct HwTimerQuery;
struct HwVertexBufferInfo;
struct HwVertexBuffer;
struct HwDescriptorSetLayout;
struct HwDescriptorSet;
struct HwMemoryMappedBuffer;
/*
* A handle to a backend resource. HandleBase is for internal use only.
@@ -151,12 +153,14 @@ using RenderPrimitiveHandle = Handle<HwRenderPrimitive>;
using RenderTargetHandle = Handle<HwRenderTarget>;
using StreamHandle = Handle<HwStream>;
using SwapChainHandle = Handle<HwSwapChain>;
using SyncHandle = Handle<HwSync>;
using TextureHandle = Handle<HwTexture>;
using TimerQueryHandle = Handle<HwTimerQuery>;
using VertexBufferHandle = Handle<HwVertexBuffer>;
using VertexBufferInfoHandle = Handle<HwVertexBufferInfo>;
using DescriptorSetLayoutHandle = Handle<HwDescriptorSetLayout>;
using DescriptorSetHandle = Handle<HwDescriptorSet>;
using MemoryMappedBufferHandle = Handle<HwMemoryMappedBuffer>;
} // namespace filament::backend
+5 -1
View File
@@ -29,6 +29,7 @@
namespace filament::backend {
class CallbackHandler;
class Driver;
/**
@@ -42,6 +43,9 @@ public:
struct SwapChain {};
struct Fence {};
struct Stream {};
struct Sync {};
using SyncCallback = void(*)(Sync* UTILS_NONNULL sync, void* UTILS_NULLABLE userData);
class ExternalImageHandle;
@@ -232,7 +236,7 @@ public:
* @return nullptr on failure, or a pointer to the newly created driver.
*/
virtual Driver* UTILS_NULLABLE createDriver(void* UTILS_NULLABLE sharedContext,
const DriverConfig& driverConfig) noexcept = 0;
const DriverConfig& driverConfig) = 0;
/**
* Processes the platform's event queue when called from its primary event-handling thread.
@@ -27,12 +27,12 @@ namespace filament::backend {
* A PresentCallable is a callable object that, when called, schedules a frame for presentation on
* a SwapChain.
*
* Typically, Filament's backend is responsible scheduling a frame's presentation. However, there
* are certain cases where the application might want to control when a frame is scheduled for
* Typically, Filament's backend is responsible for scheduling a frame's presentation. However,
* there are certain cases where the application might want to control when a frame is scheduled for
* presentation.
*
* For example, on iOS, UIKit elements can be synchronized to 3D content by scheduling a present
* within a CATransation:
* within a CATransaction:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* void myFrameScheduledCallback(PresentCallable presentCallable, void* user) {
@@ -55,12 +55,13 @@ namespace filament::backend {
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* @remark Only Filament's Metal backend supports PresentCallables and frame callbacks. Other
* backends ignore the callback (which will never be called) and proceed normally.
* @remark The PresentCallable mechanism for user-controlled presentation is only supported by
* Filament's Metal backend. On other backends, the FrameScheduledCallback is still invoked, but the
* PresentCallable passed to it is a no-op and calling it has no effect.
*
* Applications *must* call each PresentCallable they receive. Each PresentCallable represents a
* frame that is waiting to be presented. If an application fails to call a PresentCallable, a
* memory leak could occur. To "cancel" the presentation of a frame, pass false to the
* When using the Metal backend, applications *must* call each PresentCallable they receive. Each
* PresentCallable represents a frame that is waiting to be presented, and failing to call it
* will result in a memory leak. To "cancel" the presentation of a frame, pass false to the
* PresentCallable, which will cancel the presentation of the frame and release associated memory.
*
* @see Renderer, SwapChain::setFrameScheduledCallback
@@ -69,6 +70,7 @@ class UTILS_PUBLIC PresentCallable {
public:
using PresentFn = void(*)(bool presentFrame, void* user);
static void noopPresent(bool, void*) {}
PresentCallable(PresentFn fn, void* user) noexcept;
~PresentCallable() noexcept = default;
+2 -6
View File
@@ -50,11 +50,7 @@ public:
descriptor_binding_t binding;
};
struct SpecializationConstant {
using Type = std::variant<int32_t, float, bool>;
uint32_t id; // id set in glsl
Type value; // value and type
};
using SpecializationConstant = std::variant<int32_t, float, bool>;
struct Uniform { // For ES2 support
utils::CString name; // full qualified name of the uniform field
@@ -118,7 +114,7 @@ public:
Program& multiview(bool multiview) noexcept;
// For ES2 support only...
Program& uniforms(uint32_t index, utils::CString name, UniformInfo uniforms) noexcept;
Program& uniforms(uint32_t index, utils::CString name, UniformInfo uniforms);
Program& attributes(AttributesInfo attributes) noexcept;
//
@@ -85,6 +85,15 @@ public:
*/
virtual bool isSRGBSwapChainSupported() const noexcept;
/**
* Return whether createSwapChain supports the SWAP_CHAIN_CONFIG_MSAA_*_SAMPLES flag.
* The default implementation returns false.
*
* @param samples The number of samples
* @return true if SWAP_CHAIN_CONFIG_MSAA_*_SAMPLES is supported, false otherwise.
*/
virtual bool isMSAASwapChainSupported(uint32_t samples) const noexcept;
/**
* Return whether protected contexts are supported by this backend.
* If protected context are supported, the SWAP_CHAIN_CONFIG_PROTECTED_CONTENT flag can be
@@ -103,7 +112,7 @@ public:
*
*/
virtual SwapChain* UTILS_NULLABLE createSwapChain(
void* UTILS_NULLABLE nativeWindow, uint64_t flags) noexcept = 0;
void* UTILS_NULLABLE nativeWindow, uint64_t flags) = 0;
/**
* Called by the driver create a headless SwapChain.
@@ -117,7 +126,7 @@ public:
* A void* might be enough.
*/
virtual SwapChain* UTILS_NULLABLE createSwapChain(
uint32_t width, uint32_t height, uint64_t flags) noexcept = 0;
uint32_t width, uint32_t height, uint64_t flags) = 0;
/**
* Called by the driver to destroys the SwapChain
@@ -276,6 +285,26 @@ public:
*/
virtual backend::FenceStatus waitFence(Fence* UTILS_NONNULL fence, uint64_t timeout) noexcept;
// --------------------------------------------------------------------------------------------
// Sync support
/**
* Creates a Sync. These can be used for frame synchronization externally
* (certain platform implementations can be exported to handles that can
* be used in other processes).
*
* @return A Sync object.
*/
virtual Platform::Sync* UTILS_NONNULL createSync() noexcept;
/**
* Destroys a sync. If called with a sync not created by this platform
* object, this will lead to undefined behavior.
*
* @param sync The sync to destroy, that was created by this platform
* instance.
*/
virtual void destroySync(Platform::Sync* UTILS_NONNULL sync) noexcept;
// --------------------------------------------------------------------------------------------
// Streaming support
@@ -40,7 +40,7 @@ protected:
// Platform Interface
Driver* createDriver(void* sharedContext,
const DriverConfig& driverConfig) noexcept override;
const DriverConfig& driverConfig) override;
// Currently returns 0
int getOSVersion() const noexcept override;
@@ -38,7 +38,7 @@ public:
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const DriverConfig& driverConfig) noexcept override;
const DriverConfig& driverConfig) override;
int getOSVersion() const noexcept final { return 0; }
@@ -80,7 +80,7 @@ protected:
* Initializes EGL, creates the OpenGL context and returns a concrete Driver implementation
* that supports OpenGL/OpenGL ES.
*/
Driver* createDriver(void* sharedContext, const DriverConfig& driverConfig) noexcept override;
Driver* createDriver(void* sharedContext, const DriverConfig& driverConfig) override;
/**
* This returns zero. This method can be overridden to return something more useful.
@@ -98,10 +98,11 @@ protected:
void terminate() noexcept override;
bool isProtectedContextSupported() const noexcept override;
bool isSRGBSwapChainSupported() const noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
bool isMSAASwapChainSupported(uint32_t samples) const noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
bool isSwapChainProtected(SwapChain* swapChain) noexcept override;
@@ -167,6 +168,7 @@ protected:
EGLConfig mEGLConfig = EGL_NO_CONFIG_KHR;
Config mContextAttribs;
std::vector<EGLContext> mAdditionalContexts;
bool mMSAA4XSupport = false;
// supported extensions detected at runtime
struct {
@@ -217,6 +219,8 @@ private:
return makeCurrent(mCurrentContext, drawSurface, readSurface);
}
} egl{ mEGLDisplay };
bool checkIfMSAASwapChainSupported(uint32_t samples) const noexcept;
};
} // namespace filament::backend
@@ -58,6 +58,17 @@ public:
ExternalImageDescAndroid UTILS_PUBLIC getExternalImageDesc(ExternalImageHandle externalImage) noexcept;
/**
* Converts a sync to an external file descriptor, if possible. Accepts an
* opaque handle to a sync, as well as a pointer to where the fd should be
* stored.
* @param sync The sync to be converted to a file descriptor.
* @param fd A pointer to where the file descriptor should be stored.
* @return `true` on success, `false` on failure. The default implementation
* returns `false`.
*/
bool convertSyncToFd(Platform::Sync* sync, int* fd) noexcept;
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
@@ -69,11 +80,15 @@ protected:
int getOSVersion() const noexcept override;
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
const Platform::DriverConfig& driverConfig) override;
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
struct SyncEGLAndroid : public Platform::Sync {
EGLSyncKHR sync;
};
void terminate() noexcept override;
void beginFrame(
@@ -89,9 +104,10 @@ protected:
*/
void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept override;
Stream* createStream(void* nativeStream) noexcept override;
void destroyStream(Stream* stream) noexcept override;
Platform::Sync* createSync() noexcept override;
void destroySync(Platform::Sync* sync) noexcept override;
void attach(Stream* stream, intptr_t tname) noexcept override;
void detach(Stream* stream) noexcept override;
void updateTexImage(Stream* stream, int64_t* timestamp) noexcept override;
@@ -29,7 +29,7 @@ public:
PlatformEGLHeadless() noexcept;
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
const Platform::DriverConfig& driverConfig) override;
protected:
bool isOpenGL() const noexcept override;
@@ -39,7 +39,7 @@ protected:
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const DriverConfig& driverConfig) noexcept override;
const DriverConfig& driverConfig) override;
int getOSVersion() const noexcept final override { return 0; }
@@ -55,9 +55,9 @@ protected:
void commit(SwapChain* swapChain) noexcept override;
private:
Display *mGLXDisplay;
GLXContext mGLXContext;
GLXFBConfig* mGLXConfig;
Display* mGLXDisplay;
GLXContext mGLXContext{};
GLXFBConfig mGLXConfig{};
GLXPbuffer mDummySurface;
std::vector<GLXPbuffer> mPBuffers;
};
@@ -36,7 +36,7 @@ public:
PlatformMetal();
~PlatformMetal() noexcept override;
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) override;
int getOSVersion() const noexcept override { return 0; }
/**
@@ -43,7 +43,7 @@ protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedGLContext, const DriverConfig& driverConfig) noexcept override;
Driver* createDriver(void* sharedGLContext, const DriverConfig& driverConfig) override;
int getOSVersion() const noexcept final override { return 0; }
@@ -38,7 +38,7 @@ protected:
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept override;
const Platform::DriverConfig& driverConfig) override;
int getOSVersion() const noexcept final override { return 0; }
@@ -61,8 +61,12 @@ protected:
HWND mHWnd = NULL;
HDC mWhdc = NULL;
PIXELFORMATDESCRIPTOR mPfd = {};
std::vector<HGLRC> mAdditionalContexts;
std::vector<int> mAttribs;
// For shared contexts
static constexpr int SHARED_CONTEXT_NUM = 1;
std::vector<HGLRC> mAdditionalContexts;
std::atomic<int> mNextFreeSharedContextIndex{0};
};
} // namespace filament::backend
@@ -34,7 +34,7 @@ protected:
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept override;
const Platform::DriverConfig& driverConfig) override;
int getOSVersion() const noexcept override;
@@ -17,8 +17,9 @@
#ifndef TNT_FILAMENT_BACKEND_PLATFORMS_VULKANPLATFORM_H
#define TNT_FILAMENT_BACKEND_PLATFORMS_VULKANPLATFORM_H
#include <backend/Platform.h>
#include <backend/CallbackHandler.h>
#include <backend/DriverEnums.h>
#include <backend/Platform.h>
#include <bluevk/BlueVK.h>
@@ -29,9 +30,9 @@
#include <cstddef>
#include <functional>
#include <string>
#include <tuple>
#include <unordered_set>
#include <string>
#include <stddef.h>
#include <stdint.h>
@@ -45,6 +46,10 @@ using SwapChain = Platform::SwapChain;
*/
struct VulkanPlatformPrivate;
// Forward declare the fence status that will be maintained by the command
// buffer manager.
struct VulkanCmdFence;
/**
* A Platform interface that creates a Vulkan backend.
*/
@@ -114,7 +119,7 @@ public:
~VulkanPlatform() override;
Driver* createDriver(void* sharedContext,
Platform::DriverConfig const& driverConfig) noexcept override;
Platform::DriverConfig const& driverConfig) override;
int getOSVersion() const noexcept override {
return 0;
@@ -229,6 +234,25 @@ public:
virtual SwapChainPtr createSwapChain(void* nativeWindow, uint64_t flags = 0,
VkExtent2D extent = {0, 0});
/**
* Creates a Platform::Sync object, which tracks a fence and its status,
* and allows conversion to an external sync.
* @param fence The underlying VkFence to use for synchronization.
* @param fenceStatus An object tracking the fence's state
* @return A Platform::Sync object tracking the provided fence.
*/
virtual Platform::Sync* createSync(VkFence fence,
std::shared_ptr<VulkanCmdFence> fenceStatus) noexcept;
/**
* Destroys a sync. If called with a sync not created by this platform
* object, this will lead to undefined behavior.
*
* @param sync The sync to destroy, which was created by this platform
* instance.
*/
virtual void destroySync(Platform::Sync* sync) noexcept;
/**
* Allows implementers to provide instance extensions that they'd like to include in the
* instance creation.
@@ -408,12 +432,19 @@ public:
}
protected:
struct VulkanSync : public Platform::Sync {
VkFence fence;
std::shared_ptr<VulkanCmdFence> fenceStatus;
};
virtual ExtensionSet getSwapchainInstanceExtensions() const;
using SurfaceBundle = std::tuple<VkSurfaceKHR, VkExtent2D>;
virtual SurfaceBundle createVkSurfaceKHR(void* nativeWindow, VkInstance instance,
uint64_t flags) const noexcept;
virtual VkExternalFenceHandleTypeFlagBits getFenceExportFlags() const noexcept;
private:
// Platform dependent helper methods
static ExtensionSet getSwapchainInstanceExtensionsImpl();
@@ -44,6 +44,17 @@ public:
virtual ImageData createVkImageFromExternal(ExternalImageHandleRef image) const override;
/**
* Converts a sync to an external file descriptor, if possible. Accepts an
* opaque handle to a sync, as well as a pointer to where the fd should be
* stored.
* @param sync The sync to be converted to a file descriptor.
* @param fd A pointer to where the file descriptor should be stored.
* @return `true` on success, `false` on failure. The default implementation
* returns `false`.
*/
bool convertSyncToFd(Platform::Sync* sync, int* fd) const noexcept;
protected:
virtual ExtensionSet getSwapchainInstanceExtensions() const override;
@@ -51,6 +62,8 @@ protected:
virtual SurfaceBundle createVkSurfaceKHR(void* nativeWindow, VkInstance instance,
uint64_t flags) const noexcept override;
virtual VkExternalFenceHandleTypeFlagBits getFenceExportFlags() const noexcept override;
private:
struct ExternalImageVulkanAndroid : public Platform::ExternalImage {
AHardwareBuffer* aHardwareBuffer = nullptr;
@@ -19,6 +19,16 @@
#include <backend/Platform.h>
#if defined(__linux__) && defined(FILAMENT_SUPPORTS_X11)
// Resolve the conflicts between webgpu_cpp.h and X11 defines
#undef Always
#undef Success
#undef None
#undef True
#undef False
#undef Status
#undef Bool
#endif
#include <webgpu/webgpu_cpp.h>
#include <cstdint>
@@ -62,7 +72,7 @@ public:
protected:
[[nodiscard]] Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
const Platform::DriverConfig& driverConfig) override;
private:
// returns adapter request option variations applicable for the particular
@@ -61,7 +61,7 @@ class CommandBase {
protected:
using Execute = Dispatcher::Execute;
constexpr explicit CommandBase(Execute execute) noexcept : mExecute(execute) {}
constexpr explicit CommandBase(Execute const execute) noexcept : mExecute(execute) {}
public:
// alignment of all Commands in the CommandStream
@@ -70,7 +70,7 @@ public:
}
// executes this command and returns the next one
inline CommandBase* execute(Driver& driver) {
CommandBase* execute(Driver& driver) {
// returning the next command by output parameter allows the compiler to perform the
// tail-call optimization in the function called by mExecute, however that comes at
// a cost here (writing and reading the stack at each iteration), in the end it's
@@ -80,7 +80,7 @@ public:
return reinterpret_cast<CommandBase*>(reinterpret_cast<intptr_t>(this) + next);
}
inline ~CommandBase() noexcept = default;
~CommandBase() noexcept = default;
private:
Execute mExecute;
@@ -135,7 +135,7 @@ struct CommandType<void (Driver::*)(ARGS...)> {
public:
template<typename M, typename D>
static inline void execute(M&& method, D&& driver, CommandBase* base, intptr_t* next) {
static void execute(M&& method, D&& driver, CommandBase* base, intptr_t* next) {
Command* self = static_cast<Command*>(base);
*next = align(sizeof(Command));
#if DEBUG_COMMAND_STREAM
@@ -147,15 +147,15 @@ struct CommandType<void (Driver::*)(ARGS...)> {
}
// A command can be moved
inline Command(Command&& rhs) noexcept = default;
Command(Command&& rhs) noexcept = default;
template<typename... A>
inline explicit constexpr Command(Execute execute, A&& ... args)
explicit constexpr Command(Execute const execute, A&& ... args) noexcept
: CommandBase(execute), mArgs(std::forward<A>(args)...) {
}
// placement new declared as "throw" to avoid the compiler's null-check
inline void* operator new(std::size_t, void* ptr) {
void* operator new(std::size_t, void* ptr) noexcept {
assert_invariant(ptr);
return ptr;
}
@@ -171,8 +171,9 @@ class CustomCommand : public CommandBase {
std::function<void()> mCommand;
static void execute(Driver&, CommandBase* base, intptr_t* next);
public:
inline CustomCommand(CustomCommand&& rhs) = default;
inline explicit CustomCommand(std::function<void()> cmd)
CustomCommand(CustomCommand&& rhs) = default;
explicit CustomCommand(std::function<void()> cmd)
: CommandBase(execute), mCommand(std::move(cmd)) { }
};
@@ -184,7 +185,7 @@ class NoopCommand : public CommandBase {
*next = static_cast<NoopCommand*>(self)->mNext;
}
public:
inline constexpr explicit NoopCommand(void* next) noexcept
constexpr explicit NoopCommand(void* next) noexcept
: CommandBase(execute), mNext(intptr_t((char *)next - (char *)this)) { }
};
@@ -207,8 +208,8 @@ class CommandStream {
template<typename T>
struct AutoExecute {
T closure;
inline explicit AutoExecute(T&& closure) : closure(std::forward<T>(closure)) {}
inline ~AutoExecute() { closure(); }
explicit AutoExecute(T&& closure) : closure(std::forward<T>(closure)) {}
~AutoExecute() { closure(); }
};
public:
@@ -221,7 +222,7 @@ public:
public:
#define DECL_DRIVER_API(methodName, paramsDecl, params) \
inline void methodName(paramsDecl) { \
inline void methodName(paramsDecl) noexcept { \
DEBUG_COMMAND_BEGIN(methodName, false, params); \
using Cmd = COMMAND_TYPE(methodName); \
void* const p = allocateCommand(CommandBase::align(sizeof(Cmd))); \
@@ -230,7 +231,7 @@ public:
}
#define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params) \
inline RetType methodName(paramsDecl) { \
inline RetType methodName(paramsDecl) noexcept { \
DEBUG_COMMAND_BEGIN(methodName, true, params); \
AutoExecute callOnExit([=, this](){ \
DEBUG_COMMAND_END(methodName, true); \
@@ -239,7 +240,7 @@ public:
}
#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) \
inline RetType methodName(paramsDecl) { \
inline RetType methodName(paramsDecl) noexcept { \
DEBUG_COMMAND_BEGIN(methodName, false, params); \
RetType result = mDriver.methodName##S(); \
using Cmd = COMMAND_TYPE(methodName##R); \
@@ -255,7 +256,7 @@ public:
// This is for debugging only. Currently, CircularBuffer can only be written from a
// single thread. In debug builds we assert this condition.
// Call this first in the render loop.
inline void debugThreading() noexcept {
void debugThreading() noexcept {
#ifndef NDEBUG
mThreadId = utils::ThreadUtils::getThreadId();
#endif
@@ -281,11 +282,11 @@ public:
*/
template<typename PodType,
typename = typename std::enable_if<std::is_trivially_destructible<PodType>::value>::type>
inline PodType* allocatePod(
PodType* allocatePod(
size_t count = 1, size_t alignment = alignof(PodType)) noexcept;
private:
inline void* allocateCommand(size_t size) {
void* allocateCommand(size_t const size) noexcept {
assert_invariant(utils::ThreadUtils::isThisThread(mThreadId));
return mCurrentBuffer.allocate(size);
}
@@ -27,6 +27,8 @@
#include <backend/AcquiredImage.h>
#include <utils/CString.h>
#include <utils/ImmutableCString.h>
#include <utils/FixedCapacityVector.h>
#include <utils/compiler.h>
#include <functional>
@@ -71,7 +73,11 @@ public:
virtual ShaderModel getShaderModel() const noexcept = 0;
// The shader language used for shaders for this driver, used to inform matdbg.
// The shader languages used for shaders for this driver in order of preference, used to inform
// matdbg.
//
// The `preferredLanguage` is only a hint. If the backend supports it, it will appear first in
// the list.
//
// For OpenGL, this distinguishes whether the driver's shaders are powered by ESSL1 or ESSL3.
// This information is used by matdbg to display the correct shader code to the web UI and patch
@@ -79,7 +85,8 @@ public:
//
// Metal shaders can either be MSL or Metal libraries, but at time of writing, matdbg can only
// interface with MSL.
virtual ShaderLanguage getShaderLanguage() const noexcept = 0;
virtual utils::FixedCapacityVector<ShaderLanguage> getShaderLanguages(
ShaderLanguage preferredLanguage) const noexcept = 0;
// Returns the dispatcher. This is only called once during initialization of the CommandStream,
// so it doesn't matter that it's virtual.
@@ -107,9 +107,17 @@
#define DECL_DRIVER_API_R_N(R, N, ...) \
DECL_DRIVER_API_RETURN(R, N, PAIR_ARGS_N(ARG, ##__VA_ARGS__), PAIR_ARGS_N(PARAM, ##__VA_ARGS__))
#define DECL_DRIVER_API_TAGGED_R_N(R, N, ...) \
DECL_DRIVER_API_RETURN(R, N, PAIR_ARGS_N(ARG, ##__VA_ARGS__, utils::ImmutableCString&&, tag = {}), \
PAIR_ARGS_N(PARAM, ##__VA_ARGS__, utils::ImmutableCString&&, tag))
#define DECL_DRIVER_API_SYNCHRONOUS_N(R, N, ...) \
DECL_DRIVER_API_SYNCHRONOUS(R, N, PAIR_ARGS_N(ARG, ##__VA_ARGS__), PAIR_ARGS_N(PARAM, ##__VA_ARGS__))
#define DECL_DRIVER_API_SYNCHRONOUS_TAGGED_N(R, N, ...) \
DECL_DRIVER_API_SYNCHRONOUS(R, N, PAIR_ARGS_N(ARG, ##__VA_ARGS__, utils::ImmutableCString, tag = {}), \
PAIR_ARGS_N(PARAM, ##__VA_ARGS__, utils::ImmutableCString, tag))
// on some compilers the ##__VA_ARGS__ hack is not supported, so we can't handle 0-parameter APIs
// with DECL_DRIVER_API_SYNCHRONOUS_N
#define DECL_DRIVER_API_SYNCHRONOUS_0(R, N) \
@@ -165,35 +173,31 @@ DECL_DRIVER_API_0(finish)
// reset state tracking, if the driver does any state tracking (e.g. GL)
DECL_DRIVER_API_0(resetState)
DECL_DRIVER_API_N(setDebugTag,
backend::HandleBase::HandleId, handleId,
utils::CString, tag)
/*
* Creating driver objects
* -----------------------
*/
DECL_DRIVER_API_R_N(backend::VertexBufferInfoHandle, createVertexBufferInfo,
DECL_DRIVER_API_TAGGED_R_N(backend::VertexBufferInfoHandle, createVertexBufferInfo,
uint8_t, bufferCount,
uint8_t, attributeCount,
backend::AttributeArray, attributes)
DECL_DRIVER_API_R_N(backend::VertexBufferHandle, createVertexBuffer,
DECL_DRIVER_API_TAGGED_R_N(backend::VertexBufferHandle, createVertexBuffer,
uint32_t, vertexCount,
backend::VertexBufferInfoHandle, vbih)
DECL_DRIVER_API_R_N(backend::IndexBufferHandle, createIndexBuffer,
DECL_DRIVER_API_TAGGED_R_N(backend::IndexBufferHandle, createIndexBuffer,
backend::ElementType, elementType,
uint32_t, indexCount,
backend::BufferUsage, usage)
DECL_DRIVER_API_R_N(backend::BufferObjectHandle, createBufferObject,
DECL_DRIVER_API_TAGGED_R_N(backend::BufferObjectHandle, createBufferObject,
uint32_t, byteCount,
backend::BufferObjectBinding, bindingType,
backend::BufferUsage, usage)
DECL_DRIVER_API_R_N(backend::TextureHandle, createTexture,
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTexture,
backend::SamplerType, target,
uint8_t, levels,
backend::TextureFormat, format,
@@ -203,19 +207,19 @@ DECL_DRIVER_API_R_N(backend::TextureHandle, createTexture,
uint32_t, depth,
backend::TextureUsage, usage)
DECL_DRIVER_API_R_N(backend::TextureHandle, createTextureView,
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureView,
backend::TextureHandle, texture,
uint8_t, baseLevel,
uint8_t, levelCount)
DECL_DRIVER_API_R_N(backend::TextureHandle, createTextureViewSwizzle,
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureViewSwizzle,
backend::TextureHandle, texture,
backend::TextureSwizzle, r,
backend::TextureSwizzle, g,
backend::TextureSwizzle, b,
backend::TextureSwizzle, a)
DECL_DRIVER_API_R_N(backend::TextureHandle, createTextureExternalImage2,
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureExternalImage2,
backend::SamplerType, target,
backend::TextureFormat, format,
uint32_t, width,
@@ -223,7 +227,7 @@ DECL_DRIVER_API_R_N(backend::TextureHandle, createTextureExternalImage2,
backend::TextureUsage, usage,
backend::Platform::ExternalImageHandleRef, image)
DECL_DRIVER_API_R_N(backend::TextureHandle, createTextureExternalImage,
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureExternalImage,
backend::SamplerType, target,
backend::TextureFormat, format,
uint32_t, width,
@@ -231,7 +235,7 @@ DECL_DRIVER_API_R_N(backend::TextureHandle, createTextureExternalImage,
backend::TextureUsage, usage,
void*, image)
DECL_DRIVER_API_R_N(backend::TextureHandle, createTextureExternalImagePlane,
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, createTextureExternalImagePlane,
backend::TextureFormat, format,
uint32_t, width,
uint32_t, height,
@@ -239,7 +243,7 @@ DECL_DRIVER_API_R_N(backend::TextureHandle, createTextureExternalImagePlane,
void*, image,
uint32_t, plane)
DECL_DRIVER_API_R_N(backend::TextureHandle, importTexture,
DECL_DRIVER_API_TAGGED_R_N(backend::TextureHandle, importTexture,
intptr_t, id,
backend::SamplerType, target,
uint8_t, levels,
@@ -250,17 +254,17 @@ DECL_DRIVER_API_R_N(backend::TextureHandle, importTexture,
uint32_t, depth,
backend::TextureUsage, usage)
DECL_DRIVER_API_R_N(backend::RenderPrimitiveHandle, createRenderPrimitive,
DECL_DRIVER_API_TAGGED_R_N(backend::RenderPrimitiveHandle, createRenderPrimitive,
backend::VertexBufferHandle, vbh,
backend::IndexBufferHandle, ibh,
backend::PrimitiveType, pt)
DECL_DRIVER_API_R_N(backend::ProgramHandle, createProgram,
DECL_DRIVER_API_TAGGED_R_N(backend::ProgramHandle, createProgram,
backend::Program&&, program)
DECL_DRIVER_API_R_0(backend::RenderTargetHandle, createDefaultRenderTarget)
DECL_DRIVER_API_TAGGED_R_N(backend::RenderTargetHandle, createDefaultRenderTarget)
DECL_DRIVER_API_R_N(backend::RenderTargetHandle, createRenderTarget,
DECL_DRIVER_API_TAGGED_R_N(backend::RenderTargetHandle, createRenderTarget,
backend::TargetBufferFlags, targetBufferFlags,
uint32_t, width,
uint32_t, height,
@@ -270,46 +274,32 @@ DECL_DRIVER_API_R_N(backend::RenderTargetHandle, createRenderTarget,
backend::TargetBufferInfo, depth,
backend::TargetBufferInfo, stencil)
DECL_DRIVER_API_R_0(backend::FenceHandle, createFence)
DECL_DRIVER_API_TAGGED_R_N(backend::FenceHandle, createFence)
DECL_DRIVER_API_R_N(backend::SwapChainHandle, createSwapChain,
DECL_DRIVER_API_TAGGED_R_N(backend::SyncHandle, createSync)
DECL_DRIVER_API_TAGGED_R_N(backend::SwapChainHandle, createSwapChain,
void*, nativeWindow,
uint64_t, flags)
DECL_DRIVER_API_R_N(backend::SwapChainHandle, createSwapChainHeadless,
DECL_DRIVER_API_TAGGED_R_N(backend::SwapChainHandle, createSwapChainHeadless,
uint32_t, width,
uint32_t, height,
uint64_t, flags)
DECL_DRIVER_API_R_0(backend::TimerQueryHandle, createTimerQuery)
DECL_DRIVER_API_TAGGED_R_N(backend::TimerQueryHandle, createTimerQuery)
DECL_DRIVER_API_R_N(backend::DescriptorSetLayoutHandle, createDescriptorSetLayout,
DECL_DRIVER_API_TAGGED_R_N(backend::DescriptorSetLayoutHandle, createDescriptorSetLayout,
backend::DescriptorSetLayout&&, info)
DECL_DRIVER_API_R_N(backend::DescriptorSetHandle, createDescriptorSet,
DECL_DRIVER_API_TAGGED_R_N(backend::DescriptorSetHandle, createDescriptorSet,
backend::DescriptorSetLayoutHandle, dslh)
DECL_DRIVER_API_N(updateDescriptorSetBuffer,
backend::DescriptorSetHandle, dsh,
backend::descriptor_binding_t, binding,
DECL_DRIVER_API_TAGGED_R_N(backend::MemoryMappedBufferHandle, mapBuffer,
backend::BufferObjectHandle, boh,
uint32_t, offset,
uint32_t, size
)
DECL_DRIVER_API_N(updateDescriptorSetTexture,
backend::DescriptorSetHandle, dsh,
backend::descriptor_binding_t, binding,
backend::TextureHandle, th,
SamplerParams, params
)
DECL_DRIVER_API_N(bindDescriptorSet,
backend::DescriptorSetHandle, dsh,
backend::descriptor_set_t, set,
backend::DescriptorSetOffsetArray&&, offsets
)
size_t, offset,
size_t, size,
backend::MapBufferAccessFlags, access)
/*
* Destroying driver objects
@@ -319,7 +309,7 @@ DECL_DRIVER_API_N(bindDescriptorSet,
DECL_DRIVER_API_N(destroyVertexBuffer, backend::VertexBufferHandle, vbh)
DECL_DRIVER_API_N(destroyVertexBufferInfo, backend::VertexBufferInfoHandle, vbih)
DECL_DRIVER_API_N(destroyIndexBuffer, backend::IndexBufferHandle, ibh)
DECL_DRIVER_API_N(destroyBufferObject, backend::BufferObjectHandle, ibh)
DECL_DRIVER_API_N(destroyBufferObject, backend::BufferObjectHandle, boh)
DECL_DRIVER_API_N(destroyRenderPrimitive, backend::RenderPrimitiveHandle, rph)
DECL_DRIVER_API_N(destroyProgram, backend::ProgramHandle, ph)
DECL_DRIVER_API_N(destroyTexture, backend::TextureHandle, th)
@@ -328,8 +318,10 @@ DECL_DRIVER_API_N(destroySwapChain, backend::SwapChainHandle, sch)
DECL_DRIVER_API_N(destroyStream, backend::StreamHandle, sh)
DECL_DRIVER_API_N(destroyTimerQuery, backend::TimerQueryHandle, sh)
DECL_DRIVER_API_N(destroyFence, backend::FenceHandle, fh)
DECL_DRIVER_API_N(destroySync, backend::SyncHandle, sh)
DECL_DRIVER_API_N(destroyDescriptorSetLayout, backend::DescriptorSetLayoutHandle, dslh)
DECL_DRIVER_API_N(destroyDescriptorSet, backend::DescriptorSetHandle, dsh)
DECL_DRIVER_API_N(unmapBuffer, backend::MemoryMappedBufferHandle, mmbh)
/*
* Synchronous APIs
@@ -337,13 +329,16 @@ DECL_DRIVER_API_N(destroyDescriptorSet, backend::DescriptorSetHandle, ds
*/
DECL_DRIVER_API_SYNCHRONOUS_0(void, terminate)
DECL_DRIVER_API_SYNCHRONOUS_N(backend::StreamHandle, createStreamNative, void*, stream)
DECL_DRIVER_API_SYNCHRONOUS_0(backend::StreamHandle, createStreamAcquired)
DECL_DRIVER_API_SYNCHRONOUS_TAGGED_N(backend::StreamHandle, createStreamNative, void*, stream)
DECL_DRIVER_API_SYNCHRONOUS_TAGGED_N(backend::StreamHandle, createStreamAcquired)
DECL_DRIVER_API_SYNCHRONOUS_N(void, setAcquiredImage, backend::StreamHandle, stream, void*, image, const math::mat3f&, transform, backend::CallbackHandler*, handler, backend::StreamCallback, cb, void*, userData)
DECL_DRIVER_API_SYNCHRONOUS_N(void, setStreamDimensions, backend::StreamHandle, stream, uint32_t, width, uint32_t, height)
DECL_DRIVER_API_SYNCHRONOUS_N(int64_t, getStreamTimestamp, backend::StreamHandle, stream)
DECL_DRIVER_API_SYNCHRONOUS_N(void, updateStreams, backend::DriverApi*, driver)
DECL_DRIVER_API_SYNCHRONOUS_N(backend::FenceStatus, getFenceStatus, backend::FenceHandle, fh)
DECL_DRIVER_API_SYNCHRONOUS_N(backend::FenceStatus, fenceWait, backend::FenceHandle, fh, uint64_t, timeout)
DECL_DRIVER_API_SYNCHRONOUS_N(void, getPlatformSync, backend::SyncHandle, sh,
backend::CallbackHandler*, handler, backend::Platform::SyncCallback, cb, void*, userData)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isTextureFormatSupported, backend::TextureFormat, format)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isTextureSwizzleSupported)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isTextureFormatMipmappable, backend::TextureFormat, format)
@@ -353,6 +348,7 @@ DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameBufferFetchMultiSampleSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameTimeSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isAutoDepthResolveSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isSRGBSwapChainSupported)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isMSAASwapChainSupported, uint32_t, samples)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isProtectedContentSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isStereoSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isParallelShaderCompileSupported)
@@ -367,7 +363,7 @@ DECL_DRIVER_API_SYNCHRONOUS_0(size_t, getMaxArrayTextureLayers)
DECL_DRIVER_API_SYNCHRONOUS_0(math::float2, getClipSpaceParams)
DECL_DRIVER_API_SYNCHRONOUS_N(void, setupExternalImage2, backend::Platform::ExternalImageHandleRef, image)
DECL_DRIVER_API_SYNCHRONOUS_N(void, setupExternalImage, void*, image)
DECL_DRIVER_API_SYNCHRONOUS_N(backend::TimerQueryResult, getTimerQueryValue, backend::TimerQueryHandle, query, uint64_t*, elapsedTime)
DECL_DRIVER_API_SYNCHRONOUS_N(backend::TimerQueryResult, getTimerQueryValue, backend::TimerQueryHandle, tqh, uint64_t*, elapsedTime)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isWorkaroundNeeded, backend::Workaround, workaround)
DECL_DRIVER_API_SYNCHRONOUS_0(backend::FeatureLevel, getFeatureLevel)
@@ -392,16 +388,16 @@ DECL_DRIVER_API_N(updateBufferObject,
uint32_t, byteOffset)
DECL_DRIVER_API_N(registerBufferObjectStreams,
backend::BufferObjectHandle, ibh,
backend::BufferObjectHandle, boh,
backend::BufferObjectStreamDescriptor&&, streams)
DECL_DRIVER_API_N(updateBufferObjectUnsynchronized,
backend::BufferObjectHandle, ibh,
backend::BufferObjectHandle, boh,
backend::BufferDescriptor&&, data,
uint32_t, byteOffset)
DECL_DRIVER_API_N(resetBufferObject,
backend::BufferObjectHandle, ibh)
backend::BufferObjectHandle, boh)
DECL_DRIVER_API_N(update3DImage,
backend::TextureHandle, th,
@@ -421,6 +417,48 @@ DECL_DRIVER_API_N(setExternalStream,
backend::TextureHandle, th,
backend::StreamHandle, sh)
DECL_DRIVER_API_N(beginTimerQuery,
backend::TimerQueryHandle, tqh)
DECL_DRIVER_API_N(endTimerQuery,
backend::TimerQueryHandle, tqh)
DECL_DRIVER_API_N(compilePrograms,
backend::CompilerPriorityQueue, priority,
backend::CallbackHandler*, handler,
backend::CallbackHandler::Callback, callback,
void*, user)
DECL_DRIVER_API_N(updateDescriptorSetBuffer,
backend::DescriptorSetHandle, dsh,
backend::descriptor_binding_t, binding,
backend::BufferObjectHandle, boh,
uint32_t, offset,
uint32_t, size
)
DECL_DRIVER_API_N(updateDescriptorSetTexture,
backend::DescriptorSetHandle, dsh,
backend::descriptor_binding_t, binding,
backend::TextureHandle, th,
SamplerParams, params
)
DECL_DRIVER_API_N(copyToMemoryMappedBuffer,
backend::MemoryMappedBufferHandle, mmbh,
size_t, offset,
backend::BufferDescriptor&&, data)
DECL_DRIVER_API_N(setPushConstant,
backend::ShaderStage, stage,
uint8_t, index,
backend::PushConstantVariant, value)
/*
* Setting rendering state
* -----------------------
*/
DECL_DRIVER_API_N(beginRenderPass,
backend::RenderTargetHandle, rth,
const backend::RenderPassParams&, params)
@@ -429,17 +467,17 @@ DECL_DRIVER_API_0(endRenderPass)
DECL_DRIVER_API_0(nextSubpass)
DECL_DRIVER_API_N(beginTimerQuery,
backend::TimerQueryHandle, query)
DECL_DRIVER_API_N(bindPipeline,
backend::PipelineState const&, state)
DECL_DRIVER_API_N(endTimerQuery,
backend::TimerQueryHandle, query)
DECL_DRIVER_API_N(bindRenderPrimitive,
backend::RenderPrimitiveHandle, rph)
DECL_DRIVER_API_N(compilePrograms,
backend::CompilerPriorityQueue, priority,
backend::CallbackHandler*, handler,
backend::CallbackHandler::Callback, callback,
void*, user)
DECL_DRIVER_API_N(bindDescriptorSet,
backend::DescriptorSetHandle, dsh,
backend::descriptor_set_t, set,
backend::DescriptorSetOffsetArray&&, offsets
)
/*
* Swap chain
@@ -458,11 +496,6 @@ DECL_DRIVER_API_N(commit,
* -----------------------
*/
DECL_DRIVER_API_N(setPushConstant,
backend::ShaderStage, stage,
uint8_t, index,
backend::PushConstantVariant, value)
DECL_DRIVER_API_N(insertEventMarker,
const char*, string)
@@ -523,12 +556,6 @@ DECL_DRIVER_API_N(blit,
math::uint2, srcOrigin,
math::uint2, size)
DECL_DRIVER_API_N(bindPipeline,
backend::PipelineState const&, state)
DECL_DRIVER_API_N(bindRenderPrimitive,
backend::RenderPrimitiveHandle, rph)
DECL_DRIVER_API_N(draw2,
uint32_t, indexOffset,
uint32_t, indexCount,
@@ -21,6 +21,7 @@
#include <utils/Allocator.h>
#include <utils/CString.h>
#include <utils/ImmutableCString.h>
#include <utils/Log.h>
#include <utils/Panic.h>
#include <utils/compiler.h>
@@ -52,16 +53,16 @@ namespace filament::backend {
class DebugTag {
public:
DebugTag();
void writePoolHandleTag(HandleBase::HandleId key, utils::CString&& tag) noexcept;
void writeHeapHandleTag(HandleBase::HandleId key, utils::CString&& tag) noexcept;
utils::CString findHandleTag(HandleBase::HandleId key) const noexcept;
void writePoolHandleTag(HandleBase::HandleId key, utils::ImmutableCString&& tag) noexcept;
void writeHeapHandleTag(HandleBase::HandleId key, utils::ImmutableCString&& tag) noexcept;
utils::ImmutableCString findHandleTag(HandleBase::HandleId key) const noexcept;
private:
// This is used to associate a tag to a handle. mDebugTags is only written the in the main
// driver thread, but it can be accessed from any thread, because it's called from handle_cast<>
// which is used by synchronous calls.
mutable utils::Mutex mDebugTagLock;
tsl::robin_map<HandleBase::HandleId, utils::CString> mDebugTags;
tsl::robin_map<HandleBase::HandleId, utils::ImmutableCString> mDebugTags;
};
/*
@@ -70,12 +71,12 @@ private:
template<size_t P0, size_t P1, size_t P2>
class HandleAllocator : public DebugTag {
public:
HandleAllocator(const char* name, size_t size) noexcept;
HandleAllocator(const char* name, size_t size);
HandleAllocator(const char* name, size_t size,
bool disableUseAfterFreeCheck, bool disableHeapHandleTags) noexcept;
bool disableUseAfterFreeCheck, bool disableHeapHandleTags);
HandleAllocator(HandleAllocator const& rhs) = delete;
HandleAllocator& operator=(HandleAllocator const& rhs) = delete;
~HandleAllocator();
~HandleAllocator() noexcept;
/*
* Constructs a D object and returns a Handle<D>
@@ -106,7 +107,7 @@ public:
*
*/
template<typename D>
Handle<D> allocate() noexcept {
Handle<D> allocate() {
Handle<D> h{ allocateHandle<D>() };
return h;
}
@@ -222,7 +223,7 @@ public:
return static_cast<Dp>(p);
}
utils::CString getHandleTag(HandleBase::HandleId key) const noexcept;
utils::ImmutableCString getHandleTag(HandleBase::HandleId key) const noexcept;
template<typename B>
bool is_valid(Handle<B>& handle) {
@@ -248,9 +249,10 @@ public:
return handle_cast<Dp>(const_cast<Handle<B>&>(handle));
}
void associateTagToHandle(HandleBase::HandleId id, utils::CString&& tag) noexcept {
// TODO: for now, only pool handles check for use-after-free, so we only keep tags for
// those
void associateTagToHandle(HandleBase::HandleId id, utils::ImmutableCString&& tag) noexcept {
if (tag.empty()) {
return;
}
uint32_t key = id;
if (UTILS_LIKELY(isPoolHandle(id))) {
// Truncate the age to get the debug tag
@@ -341,7 +343,7 @@ private:
// allocation size this is always inlined, because all these do is to call
// allocateHandleInPool()/deallocateHandleFromPool() with the right pool size.
template<typename D>
HandleBase::HandleId allocateHandle() noexcept {
HandleBase::HandleId allocateHandle() {
constexpr size_t BUCKET_SIZE = getBucketSize<D>();
return allocateHandleInPool<BUCKET_SIZE>();
}
@@ -357,7 +359,7 @@ private:
// the code generated is not trivial (even if it's not insane either).
template<size_t SIZE>
UTILS_NOINLINE
HandleBase::HandleId allocateHandleInPool() noexcept {
HandleBase::HandleId allocateHandleInPool() {
uint8_t age;
void* p = mHandleArena.alloc(SIZE, alignof(std::max_align_t), 0, &age);
if (UTILS_LIKELY(p)) {
+10 -4
View File
@@ -18,10 +18,16 @@
#include "DataReshaper.h"
#include <backend/PixelBufferDescriptor.h>
#include <backend/DriverEnums.h>
#include <utils/BitmaskEnum.h>
#include <utils/compiler.h>
#include <utils/CString.h>
#include <cstddef>
#include <cstdint>
#include <utility>
#include <string_view>
namespace filament::backend {
@@ -636,7 +642,7 @@ bool reshape(const PixelBufferDescriptor& data, PixelBufferDescriptor& reshaped)
switch (data.type) {
case PixelDataType::BYTE:
case PixelDataType::UBYTE: {
uint8_t* bytes = (uint8_t*) malloc(reshapedSize);
uint8_t* bytes = static_cast<uint8_t*>(malloc(reshapedSize));
DataReshaper::reshape<uint8_t, 3, 4>(bytes, data.buffer, data.size);
PixelBufferDescriptor pbd(bytes, reshapedSize, reshapedFormat, data.type,
data.alignment, data.left, data.top, data.stride, freeFunc);
@@ -646,7 +652,7 @@ bool reshape(const PixelBufferDescriptor& data, PixelBufferDescriptor& reshaped)
case PixelDataType::SHORT:
case PixelDataType::USHORT:
case PixelDataType::HALF: {
uint8_t* bytes = (uint8_t*) malloc(reshapedSize);
uint8_t* bytes = static_cast<uint8_t*>(malloc(reshapedSize));
DataReshaper::reshape<uint16_t, 3, 4>(bytes, data.buffer, data.size);
PixelBufferDescriptor pbd(bytes, reshapedSize, reshapedFormat, data.type,
data.alignment, data.left, data.top, data.stride, freeFunc);
@@ -655,7 +661,7 @@ bool reshape(const PixelBufferDescriptor& data, PixelBufferDescriptor& reshaped)
}
case PixelDataType::INT:
case PixelDataType::UINT: {
uint8_t* bytes = (uint8_t*) malloc(reshapedSize);
uint8_t* bytes = static_cast<uint8_t*>(malloc(reshapedSize));
DataReshaper::reshape<uint32_t, 3, 4>(bytes, data.buffer, data.size);
PixelBufferDescriptor pbd(bytes, reshapedSize, reshapedFormat, data.type,
data.alignment, data.left, data.top, data.stride, freeFunc);
@@ -663,7 +669,7 @@ bool reshape(const PixelBufferDescriptor& data, PixelBufferDescriptor& reshaped)
return true;
}
case PixelDataType::FLOAT: {
uint8_t* bytes = (uint8_t*) malloc(reshapedSize);
uint8_t* bytes = static_cast<uint8_t*>(malloc(reshapedSize));
DataReshaper::reshape<float, 3, 4>(bytes, data.buffer, data.size);
PixelBufferDescriptor pbd(bytes, reshapedSize, reshapedFormat, data.type,
data.alignment, data.left, data.top, data.stride, freeFunc);
+1 -1
View File
@@ -20,7 +20,7 @@
namespace filament::backend {
CallbackManager::CallbackManager(DriverBase& driver) noexcept
CallbackManager::CallbackManager(DriverBase& driver)
: mDriver(driver), mCallbacks(1) {
}
+2 -2
View File
@@ -51,7 +51,7 @@ class CallbackManager {
public:
using Handle = Container::const_iterator;
explicit CallbackManager(DriverBase& driver) noexcept;
explicit CallbackManager(DriverBase& driver);
~CallbackManager() noexcept;
@@ -78,7 +78,7 @@ private:
return --mCallbacks.end();
}
Container::iterator allocateNewSlot() noexcept {
Container::iterator allocateNewSlot() {
std::lock_guard const lock(mLock);
auto curr = --mCallbacks.end();
mCallbacks.emplace_back();
+24
View File
@@ -38,6 +38,11 @@
#include <stdlib.h>
#include <string.h>
#if defined(WIN32)
# include <windows.h> // for VirtualAlloc, VirtualProtect, VirtualFree
# include <utils/unwindows.h>
#endif
using namespace utils;
namespace filament::backend {
@@ -134,6 +139,21 @@ void* CircularBuffer::alloc(size_t size) {
mprotect(guard, BLOCK_SIZE, PROT_NONE);
}
return data;
#elif defined(WIN32)
size_t const BLOCK_SIZE = getBlockSize();
// On Windows, use VirtualAlloc instead of malloc to allocate virtual memory.
// This allows us to set page protection by VirtualProtect.
void* data = VirtualAlloc(nullptr, size * 2 + BLOCK_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
FILAMENT_CHECK_POSTCONDITION(data != nullptr)
<< "couldn't allocate " << (size * 2 / 1024)
<< " KiB of virtual address space for the command buffer";
// guard page at the end
void* guard = (void*)(uintptr_t(data) + size * 2);
DWORD oldProtect = 0;
BOOL ok = VirtualProtect(guard, BLOCK_SIZE, PAGE_NOACCESS, &oldProtect);
FILAMENT_CHECK_POSTCONDITION(ok) << "VirtualProtect failed to set guard page";
return data;
#else
return ::malloc(2 * size);
#endif
@@ -150,6 +170,10 @@ void CircularBuffer::dealloc() noexcept {
mAshmemFd = -1;
}
}
#elif defined(WIN32)
if (mData) {
VirtualFree(mData, 0, MEM_RELEASE);
}
#else
::free(mData);
#endif
+10 -7
View File
@@ -57,12 +57,15 @@ static void printParameterPack(io::ostream& out, const FIRST& first, const REMAI
printParameterPack(out, rest...);
}
static UTILS_NOINLINE UTILS_UNUSED std::string extractMethodName(std::string& command) noexcept {
constexpr const char startPattern[] = "::Command<&filament::backend::Driver::";
static UTILS_NOINLINE UTILS_UNUSED std::string_view extractMethodName(std::string_view command) noexcept { // NOLINT(*-exception-escape)
constexpr char startPattern[] = "::Command<&filament::backend::Driver::";
auto pos = command.rfind(startPattern);
auto end = command.rfind('(');
pos += sizeof(startPattern) - 1;
return command.substr(pos, end-pos);
if (pos > command.size()) {
return { command.data(), command.size() };
}
return command.substr(pos, end-pos); // this can't throw by construction
}
// ------------------------------------------------------------------------------------------------
@@ -133,9 +136,9 @@ template<std::size_t... I>
void CommandType<void (Driver::*)(ARGS...)>::Command<METHOD>::log(std::index_sequence<I...>) noexcept {
#if DEBUG_COMMAND_STREAM
static_assert(UTILS_HAS_RTTI, "DEBUG_COMMAND_STREAM can only be used with RTTI");
std::string command = utils::CallStack::demangleTypeName(typeid(Command).name()).c_str();
DLOG(INFO) << extractMethodName(command) << " : size=" << sizeof(Command);
utils::io::sstream parameterPack;
CString command = CallStack::demangleTypeName(typeid(Command).name());
DLOG(INFO) << extractMethodName({command.data(), command.size()}) << " : size=" << sizeof(Command);
io::sstream parameterPack;
printParameterPack(parameterPack, std::get<I>(mArgs)...);
DLOG(INFO) << "\t" << parameterPack.c_str();
#endif
@@ -164,7 +167,7 @@ void CommandType<void (Driver::*)(ARGS...)>::Command<METHOD>::log() noexcept {
// ------------------------------------------------------------------------------------------------
void CustomCommand::execute(Driver&, CommandBase* base, intptr_t* next) {
*next = CustomCommand::align(sizeof(CustomCommand));
*next = align(sizeof(CustomCommand));
static_cast<CustomCommand*>(base)->mCommand();
static_cast<CustomCommand*>(base)->~CustomCommand();
}
+8 -1
View File
@@ -18,7 +18,14 @@
#include <private/utils/Tracing.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <algorithm>
#include <iterator>
#include <memory>
#include <mutex>
#include <utility>
namespace filament::backend {
@@ -36,7 +43,7 @@ CompilerThreadPool::~CompilerThreadPool() noexcept {
}
void CompilerThreadPool::init(uint32_t threadCount,
ThreadSetup&& threadSetup, ThreadCleanup&& threadCleanup) noexcept {
ThreadSetup&& threadSetup, ThreadCleanup&& threadCleanup) {
auto setup = std::make_shared<ThreadSetup>(std::move(threadSetup));
auto cleanup = std::make_shared<ThreadCleanup>(std::move(threadCleanup));
+1 -2
View File
@@ -47,8 +47,7 @@ public:
using Job = utils::Invocable<void()>;
using ThreadSetup = utils::Invocable<void()>;
using ThreadCleanup = utils::Invocable<void()>;
void init(uint32_t threadCount,
ThreadSetup&& threadSetup, ThreadCleanup&& threadCleanup) noexcept;
void init(uint32_t threadCount, ThreadSetup&& threadSetup, ThreadCleanup&& threadCleanup);
void terminate() noexcept;
void queue(CompilerPriorityQueue priorityQueue, program_token_t const& token, Job&& job);
Job dequeue(program_token_t const& token);

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