Compare commits

...
Author SHA1 Message Date
Benjamin Doherty 791f51dcb4 Update glslang to e3bca2a 2022-05-04 12:29:21 -07:00
Benjamin Doherty 4621f3ec5d Filament specific changes 2022-05-04 12:06:26 -07:00
Benjamin Doherty ab9c09d0d9 Update spirv-tools to 46492aa 2022-05-04 12:00:04 -07:00
Benjamin Doherty dbf51c1c7d Update SPIRV-Cross to 0c8a79b 2022-05-04 11:07:15 -07:00
Mathias Agopian ebd5f150c1 fix a potential threading/memory corruption
We can't call prepareProgram() from any thread, since it is calling
into the backend. When we had more than a certain number of commands,
we would use the jobsystem to generate them and so prepareProgram()
could end up being called from a jobsystem thread.

This is fixed by looping through all the commands once they're generated
and calling prepareProgram() then.
2022-05-03 15:16:11 -07:00
Philip Rideout 156dcb54e8 gltf_viewer: fix accidental removal of camera selector. 2022-05-03 14:33:43 -07:00
Mathias Agopian 88ef76989c Cleanup Renderer.cpp
The main changes are:

- ColorPass() and RefractionPass() are now static and moved into a 
  new RendererUtils file. These methods don't need FRenderer and are 
  more like a big "script".

- Cleaned-up includes

- Reformatted/reordered methods
2022-05-03 14:27:48 -07:00
Philip Rideout fc284af684 Rename SimpleViewer to ViewerGui.
The SimpleViewer C++ class was not viewer component like `ModelViewer`
and `<filament-viewer>`. It was actually just the UI builder used
in the `gltf_viewer` desktop app and the remote Android interface.
2022-05-03 08:10:53 -07:00
Philip Rideout 3a8685cd15 Upgrade emsdk to 3.1.9 2022-05-03 08:10:26 -07:00
Philip Rideout f035655f5b Add support for KHR_texture_basisu.
This adds a new implementation of the TextureProvider interface called
Ktx2Provider.

Tested using the KTX2 variant of the StainedGlassLamp model in the
Khronos samples repo.

Tested on WebGL 2.0 (Chrome v100), Android (Pixel 6 Pro), and Desktop
(Metal, OpenGL, and Vulkan via MoltenVK).
2022-05-02 13:15:56 -07:00
Ben Doherty f498e08d1e Update hello-pbr to work in all orientations (#5488) 2022-05-02 14:41:32 -04:00
Philip Rideout db3186a65f Remove etc2comp and astcenc from the repo. 2022-05-02 11:29:19 -07:00
Philip Rideout 248815a3e0 Fix regression with <filament-viewer>. 2022-05-02 11:09:26 -07:00
Benjamin Doherty ebb62b5d55 Release Filament 1.21.3 2022-05-02 13:17:33 -04:00
Philip Rideout b9a5ad205a Fix unit test failures.
Basis does not support DXT3 so in the past this unit test passed only
due to the enum translation bug that was recently fixed.
2022-05-02 09:48:36 -07:00
Philip Rideout 100986d8d9 Fix WebGL debug build (assert with 3-channel images) 2022-04-29 16:30:14 -07:00
Philip Rideout b7c9a36d57 Ktx2Reader: Fix error in enum translation table.
This caused DXT5 content to be interpreted as DXT3 by the GPU,
which seemed to manifest as visual artifacts in the alpha channel.
2022-04-29 16:29:53 -07:00
Philip Rideout d76551ab28 Add async interface to Ktx2Reader. 2022-04-29 14:20:57 -07:00
Mathias Agopian 92bc0752d1 repair VSM gaussian blur
When there was more than one shadowmap we would hit an assert. This 
bug was introduced recently and was due to incorrect use of the 
framegraph.
2022-04-29 12:46:37 -07:00
Mathias Agopian 657c251463 Ensure we always have 4 "safe" mip levels
A "safe" mip-level is one that has exactly half the dimensions of
the current level. In other words, we guarantee that we can halve the
dimensions 4 times without loss (i.e. odd dimension).

This is achieved by effectively padding the viewport (i.e. making the
viewport's dimensions multiple of 16). The post-processing passes
eventually take care of cropping the extra padding so the final
image is unchanged.

This is a more generic solution to dynamic resolution padding, helps
with memory allocations and helps all the algorithms that depend on
mipmaping (e.g. DoF, SSAO, Bloom).


One important improvement brought by this change is that all "final"
post-processing effects are now able to handle a sub-region of the
source, including: color-gradding, fxaa and upscaling.
2022-04-29 12:05:08 -07:00
Philip Rideout b6b8fee483 WebGL: fix isTextureFormatSupported for ETC2 formats.
It was assumed that ETC2 is supported on all ES3 devices, but WebGL on
desktop machines does not support ETC2.

Note that WebGL has its own special extension strings for compressed
textures.
2022-04-29 12:04:59 -07:00
Mathias Agopian be5b60f895 cleaner handling of shadow related uniforms
Some uniforms are needed during shadow map generation, other
during shadow sampling (color pass). We didn't have a clear separation
between them and ended up setting the UBOs that were needed only for
sampling multiple times during generation.
2022-04-29 12:04:47 -07:00
Mathias Agopian 681d31758f move the ShadowUib out of View into ShadowMapManager 2022-04-29 12:04:47 -07:00
Ben Doherty 80dc2f5c9d Move toCompressedFilamentEnum to Ktx1Reader header (#5493) 2022-04-29 14:49:54 -04:00
Mathias Agopian ce7dd7a1fb reorganize again our main UBO
- try to sort data by usage.
- clarify what post-process materials have access to (not enforced yet)
2022-04-28 10:13:20 -07:00
Mathias Agopian 85617c96a2 shrink post-process materials a bit
post-process materials don't need common_shadowing nor common_shading.

also don't rely on MIN_ROUGHNESS in .mat files, because it's not public.
2022-04-28 10:13:20 -07:00
Mathias Agopian 58760adb6a fix typo introduced in previous PR. fixes froxels. 2022-04-27 17:28:16 -07:00
Mathias Agopian 4ef0b72773 rearrange the per-view UBO (breaks materials)
- rename common_math and common_shadowing from .fs to .glsl
  because they were both included in both vertex and fragment
  shaders

- add getFragCoord() which always returns coordinates in the
  glsl convention. This is useful when used with RNGs to get
  consistant results accross backends.
2022-04-27 15:27:47 -07:00
Mathias Agopian 45631c3b81 update binding points from 8 to 12. 2022-04-27 15:27:03 -07:00
Mathias Agopian 6f6dde2579 Optimize custom rendertargets use in Renderer
we just store the "sampleable" attachments as a bitmask in 
RenderTarget instead of computing it each time.
2022-04-27 15:26:45 -07:00
Mathias Agopian e0acbe42cf update material version 2022-04-27 10:14:38 -07:00
Mathias Agopian 4f137ccf89 don't rely on frameUniform.resolution for froxelization
this is because this uniform is not well defined -- it's unclear if
it is set to the viewport or the buffer size.

also, it's not needed, and removes a couple multiplies from the shader.
2022-04-27 09:38:33 -07:00
Mathias Agopian 04010e7dd9 when matdbg is used don't terminate the program on errors 2022-04-27 08:20:00 -07:00
Mathias Agopian f4f9f331c0 CameraInfo cleanups
- add getUserViewMatrix() on CameraInfo, the "user" view matrix is the 
view matrix before we apply the world origin transform, it is needed in
 a few places, so we make it a  method so that in the future we could 
precompute it if we wanted to.

- remove worldOffset which is just the last column of worldOrigin
2022-04-26 11:32:41 -07:00
Mathias Agopian dada291f6b rename mScaling to mScalingCS 2022-04-26 11:32:41 -07:00
Mathias Agopian 18f2f8b6d4 remove unused parameters and state 2022-04-26 11:32:41 -07:00
Mathias Agopian d4117ac968 use interleavedGradientNoise() instead of custom implementaion
interleavedGradientNoise() is available in common_math, so use that
instead of our custom gradient noise RNG.
2022-04-26 11:32:41 -07:00
Mathias Agopian eccbc8c242 simplify FXAA setup
We now do all the setup math on the CPU side, but we also remove some
unnecessary computations based on assumptions that are no longer true.
2022-04-26 11:32:41 -07:00
Mathias Agopian 3cdf24f515 remove getUV() from post-process materials
it made it actually more confusing to have two version of the uv
(normalized and not). Also the unnormalized version was computed from
frameUniforms which is not great in the case of post-processing
(it just happened to work).
2022-04-26 11:30:35 -07:00
Mathias Agopian d91faf9df8 avoid unnecessary parameter copies 2022-04-26 11:28:36 -07:00
Brian Stringham d950efa6ea Changed ALL_SHADER_STATE_FLAGS initializer to support c++17, which is required for C++/CLI support. (#5465) 2022-04-26 08:59:44 -07:00
Benjamin Doherty 861d69ea7c Release Filament 1.21.2 2022-04-25 16:57:00 -04:00
LaiJF b2cc904fab Fix typo 2022-04-25 09:06:12 -07:00
Mathias Agopian 3f87b520bb ShadowMap::render() doesn't need CameraInfo anymore 2022-04-22 12:35:00 -07:00
LaiJF 135a362176 Fix typo (#5455) 2022-04-22 10:46:04 -04:00
Philip Rideout 391ebc3702 gltfio: fix progress indicator when error occurs.
The progress bar in `gltf_viewer` should not appear to hang if any
of an asset's textures fail to load.
2022-04-21 17:41:32 -07:00
Philip Rideout b4d1443720 Repair iOS build. I think. 2022-04-21 15:36:37 -07:00
Philip Rideout c06737aca2 TextureProvider fixup in ResourceLoader JNI. 2022-04-21 13:44:44 -07:00
Philip Rideout f847232296 gltfio: introduce TextureProvider API.
This allows clients to provide their own asynchronous texture decoders
for various mime-typed images. This is a plug-in component for gltfio,
in some ways similar to MaterialProvider.

There are two motivations for this: to decouple gltfio from STB and
to make it easier to integrate support for BasisU textures.

This also has the side effect of simplifying ResourceLoader, since the
texture decoding jobs have been moved out.

As part of this work, I made the "stb" CMake target into a traditional
static library. Previously we had several files called `Image.cpp`
whose sole purpose was to enable STB_IMAGE_IMPLEMENTATION.
2022-04-21 13:25:40 -07:00
LaiJF 89f06b8923 Fix typo (#5454) 2022-04-21 09:52:04 -06:00
Philip Rideout 90a2b1f3c9 Remove WebGL workaround for bloom.
Bloom now works fine (tested with Chrome 100 on a x86 MacBook) without
this workaround for overly aggressive feedback loop detection.
2022-04-20 12:07:49 -07:00
Ben Doherty 059f51338d Audit backends and test cases for correct Y orientation. (#5440) 2022-04-20 11:01:31 -06:00
LaiJF d3cea5121e Fix typo 2022-04-20 09:58:46 -07:00
LaiJF c37301d2dc Fix typo. 2022-04-19 20:27:52 -07:00
Mathias Agopian aa16778fbd don't leak Engine if the driver fail to initialize
If there is an error during the driver initialization, Engine::create() 
returns nullptr, but the FEngine was allocated and would then never
be destroyed.

mTerminated was useless because by construction it would always have
the expected value.
2022-04-19 11:49:07 -07:00
Mathias Agopian ee499ad2ca don't use a unique_ptr to hold the DFG
we can simply make it a member of FEngine.
2022-04-19 11:49:07 -07:00
Mathias Agopian 958dd5bb27 a lot of our workaround don't apply when using ANGLE 2022-04-18 20:19:09 -07:00
Mathias Agopian f988b75999 fix the 2 passes version of FSR
This version is used only on qualcomm devices. It's now forbidden to
create a program inside a renderpass. Unfortunately there was still
one codepath doing so.
2022-04-18 20:18:45 -07:00
Philip Rideout e3ccb4bb3c gltfio Animator: add resetBoneMatrices().
See #5436.
2022-04-18 15:07:35 -07:00
Philip Rideout 3f0dc6f7e6 Minor Ktx2Reader refactoring. 2022-04-18 15:02:08 -07:00
Mathias Agopian c212dd5bc7 remove the CameraInfo state from FView
this state only exists during Renderer::render(), having it outside
of view is more flexible as it give us an opportunity to adjust
camera parameter globally before drawing.

Also greatly reduced the size of RenderPass (which is a Value object).
2022-04-18 12:04:18 -07:00
LaiJF 1eceab0040 Fix typo. 2022-04-18 10:46:31 -07:00
Philip Rideout ab9d1e5956 Fix unit test. 2022-04-15 12:22:12 -07:00
Philip Rideout c906290416 Add to release notes. 2022-04-15 10:54:27 -07:00
Philip Rideout d52a24b6e9 Incorporate feedback from code review. 2022-04-15 10:48:48 -07:00
Philip Rideout 9aeec3a759 Add Ktx2Reader and BasisEncoder and use them in samples.
mipgen can now emit basis-encoded KTX2 files. Both the desktop and
web "suzanne" samples use this as a test for compressed textures.

This PR does not add KTX2 support to glTF, but it's on the way.

`BasisEncoder` has a builder style API that calls the basis encoder to
create KTX2 files. This hides some low-level BasisU features that we are
not using, like file I/O and mipmap generation.

`Ktx2Reader` is an easy-to-use API for creating Filament textures from
KTX2 files. Its API primarily consists of these two methods:

    bool requestFormat(Texture::InternalFormat format);
    Filament::Texture* load(const uint8_t* data, size_t size);

The first method is used to build an ordered list of formats that are
supported by your hardware. The second method consumes the contents of a
basis-encoded KTX2 file and attempts to produce a Filament texture with
a preferred format.

IMPORTANT: Our tools still let you use KTX1 for non-compressed images
because it is useful for HDR, but you can no longer use KTX1 for
block-compressed data.

Partial fix for #4771.
2022-04-15 10:48:48 -07:00
Mathias Agopian 550fcfe2e3 fix typos 2022-04-15 09:18:06 -07:00
Mathias Agopian b2cdf9f2b4 don't issue a flush systematically after framegraph's execute
This is only a good place for a flush *if* we're going to draw another
view (so the GPU can start working). Otherwise, it can be costly
on some drivers and unnecessary since swapbuffers will do the same.
2022-04-15 09:12:39 -07:00
Mathias Agopian 19a3fe3dce allow radius parameter for upsample bloom stage
The original article we used for our bloom (siggraph'14) called for
a radius parameter for the upsample stage. We're always using 1.0 right
now, but it is useful to keep this possibility for experimentations.
2022-04-14 14:04:32 -07:00
Mathias Agopian 754abbf78e bloom pass cleanups 2022-04-14 14:04:32 -07:00
Mathias Agopian 9b855e9a03 fix bloom downsample
a bug was introduced in 8/2020 where the downsampling filter was wrong,
due to a mistake using textureLodOffset, which obviously uses offsets
in source texel -- we were assuming destination.
2022-04-14 14:04:32 -07:00
Mathias Agopian 2534fdf92d propagate the matdbg flag to graddle 2022-04-14 14:04:15 -07:00
Mathias Agopian dab02e915e Remove deprecated Stream APIs 2022-04-14 12:51:03 -07:00
Mathias Agopian 68da1a25eb disable ANGLE optimization that hurts filament 2022-04-14 08:52:56 -07:00
Romain Guy c67b363576 Fix compilation warnings 2022-04-13 15:15:16 -07:00
Philip Rideout 5c0e7d8211 sample-gltf-viewer: fix regression with zip files.
Path resolution was broken with #5285, which only worked when the glTF
happened to be at root level. This new fix has been tested against:

- My Sponza zip file that hass all files in a "sponza" folder.
- My Bistro zip file, which has resources in a child folder relative to
  the gltf file
- A self-created flat zip using IridescentDishWithOlives, with
  everything at root level.

Side note: Bistro still fails on a Pixel 6 Pro Mali but for an unrelated
reason: (null deref in backend::TimerQueryNative::queryResultAvailable)
2022-04-13 12:18:47 -07:00
Benjamin Doherty 3d57c60840 Release Filament 1.21.1 2022-04-13 10:14:44 -06:00
Mathias Agopian 8ab2725a79 string improvements
- don't use __PRETTY_FUNCTION__ and try to parse it, __func__ is
standardized and in most case returns what we want (the function name).

- add native support for string_view in our ostream.

- uninline string support from ostream
2022-04-13 08:53:33 -07:00
Mathias Agopian ff27f8109c Use DEBUG_MARKER() only on (and on all) driver APIs 2022-04-13 08:53:14 -07:00
Philip Rideout 8e09d8bd71 Fix sRGB correctness in Ktx1Reader.
When creating a KTX file (e.g. with mipgen), you can of course choose
whether or not you want to use an sRGB format.

At load time, your app has an expectation about whether a particular
texture has an sRGB format. e.g. the glTF convention is that albedo
textures should be sRGB, while roughness textures are linear.

Before this commit, our KTX loader would look at the app's expectation,
then silently re-interpret the bits in the glTF texture in order to
match this expectation. This seems very wrong.

Instead, if the expectated format does not match the format in the KTX
file, we now print a warning.

Fixes #2422, which will also be obsoleted by our upcoming KTX2 support.
2022-04-12 11:52:36 -07:00
LaiJF d6df4cd03a Fix typo. 2022-04-12 10:57:46 -07:00
Philip Rideout df03fdf3d7 mipgen: fixups / clarification regarding sRGB.
The `g_linearized` variable was being used for two purposes: to denote
the linearity of the source format AND the linearity of the destination
format. This was confusing and is now split is `sourceIsLinear` and
`destIsLinear`.

This change has no effect on the the look of the suzanne demo.
2022-04-11 14:28:34 -07:00
Mathias Agopian 6c59945395 fix typo preventing desktop GL builds to work 2022-04-11 09:51:38 -07:00
Philip Rideout d16cc50561 Shrink BasisU transcoder.
We do not support these formats and they add bloat to the basis tables.
In a release x86 build, this reduces the transcoder size from 774 KiB to
475 KiB.
2022-04-08 15:03:30 -07:00
LaiJF e667484a94 Fix typo. (#5413) 2022-04-08 14:23:46 -07:00
LaiJF 71e5e6c6c0 Fix typo. (#5407) 2022-04-08 14:22:29 -07:00
LaiJF c1df902593 Fix typo. (#5414) 2022-04-08 14:14:47 -07:00
Mathias Agopian 3c3320a2ba we need to be able to query the version before creating OpenGLDriver. 2022-04-07 20:30:11 -07:00
Mathias Agopian 35753bc6c2 CommandStream shouldn't be copyable.
This actually avoids a copy of Dispatcher (which is pretty large)
when constructing Engine.
2022-04-07 14:07:20 -07:00
Mathias Agopian 5f7967d09c Improve HandleAllocator
Allocation and destruction of handles generates a fair amount of code
because they are synchronized and the spinlock is inlined.

So we fix this by generating the 3 (de)allocation methods we really
need, we only need 3 because we're using 3 pools. These are now 
out-of-line, which reduces size and reduces pressure on the i-cache.
Performance is not affected much because in the end it's just a
static branch (and in most case the return is elided).
2022-04-07 14:07:20 -07:00
Mathias Agopian 404b6e8af3 Improve CommandStream Dispatcher
The main change here is that instead of allocating a Dispatcher on the
heap and storing a pointer to it in the CommandStream, we now have
a Dispatcher directly inside the CommandStream.

This avoids a heap allocation and a dereference when executing a command.
2022-04-07 14:07:20 -07:00
Mathias Agopian 898c20e584 OpenGLContext cleanups
the main change here is to make OpenGLContext friendly with ES2
2022-04-07 14:07:20 -07:00
Mathias Agopian f278b76b04 gl backend version management cleanup 2022-04-07 14:07:20 -07:00
Ben Doherty 6353f17635 Releases: specify Python dependencies in requirements.txt file (#5402) 2022-04-07 11:23:03 -07:00
daemyung jang 9cae34babf Add Java binding to get skins in FilamentAsset 2022-04-07 08:53:27 -07:00
Philip Rideout c37cc61b30 Update WebGL demos again. 2022-04-06 11:03:18 -07:00
Philip Rideout 9aced8e9b8 WebGL: fix intermittent 'detached ArrayBuffer' errors.
Partial fix for #5404.
2022-04-06 10:58:30 -07:00
Philip Rideout dde060bf4d Repair iOS build. 2022-04-06 10:56:37 -07:00
Philip Rideout b60518caa5 Add libs/ktxreader, rename some things to prep for KTX2.
Changes:

- Remove the strange header-only variant of libs/image
- Rename KtxBundle => Ktx1Bundle
- Move image/KtxUtility => ktxreader/Ktx1Reader
- Add unit test for Ktx1Reader and test stub for KTX2.

Notes:

- Ktx1Bundle does not depend on Filament and is used by cmgen
  and mipgen to generate KTX files.

- Ktx1Reader has a dependency on Filament and should therefore live in
  a separate library, which it now does.
2022-04-06 10:56:37 -07:00
Philip Rideout 69000ef1f2 Fix online demo.
The `demo_*` web samples were using unpkg to refer to the Filament build
rather than using the local copy, which was inconsistent with the other
web samples.

We now use the local copy of Filament for everything except the
drag-and-drop viewer, which always uses the latest version of Filament.
2022-04-06 09:14:25 -07:00
Philip Rideout 39d6106ef2 Add BasisU to third_party. 2022-04-06 09:02:18 -07:00
Ben Doherty 96a1cbe69f Attempt to fix GitHub release asset upload (#5398) 2022-04-05 13:01:20 -07:00
Benjamin Doherty 09fe495384 Release Filament 1.21.0 2022-04-04 13:00:48 -07:00
Pavel Korolev 8457d6092d Use index offset provided by ImGui when rendering UI 2022-04-04 10:49:43 -07:00
Mathias Agopian 72c16e07ed remove Viewport::scale()
because a float->integer conversion is needed, it's better to let the
caller decide what they want.
2022-04-02 20:37:00 -07:00
Mathias Agopian 12b96cba04 minor cleanup: rename internal class attributes 2022-04-02 20:37:00 -07:00
Mathias Agopian e4d943e942 update release nodes and bump material version 2022-04-02 20:36:40 -07:00
Ben Doherty 7fa66325f3 Fix Metal validation error when reading from default SwapChain (#5392) 2022-04-01 16:37:46 -07:00
Mathias Agopian e188a7875e enable both screen-space refraction and reflection
Both "SSR" can now be used on the same material. This is made possible
by using a 2D array to store both buffers.
2022-04-01 16:22:10 -07:00
Mathias Agopian ac9822b8c8 Fix a framegraph dependency bug when writing to subresources
The dependency graph was set incorrectly when writing to a subresource
of a subresource.
2022-04-01 16:22:10 -07:00
Mathias Agopian edb5fddd03 one more step towards reflection+refraction support
With this change we are now generating refraction and reflections
buffer into their own layer of a 2D array -- so they can coexist.

This change doesn't actually enable both at the same time yet.

There are downsides to this approach:
- a 2d array of 2 layers is created even if only one of reflection or
  refraction is active. This could be fixed at the cost of more
  complexity.
- if reflections are active then refraction must use a RGBA16F texture
  instead of RGB_11_11_10, because they share the texture
2022-04-01 14:37:40 -07:00
Mathias Agopian 35f4a97e32 new framegraph API do add a pass without an execute stage 2022-04-01 14:37:40 -07:00
Mathias Agopian 487b10fdda repair and optimize matdbg
we add a checkProgramEdits() method that must be called periodically
on all materials. This is currently done at the beginning of a frame.
2022-03-31 16:52:26 -07:00
Mathias Agopian 271cda88aa Move vulkan backend implementation into the filament::backend namespace 2022-03-31 11:53:54 -07:00
Mathias Agopian 25b73ddcfa Move opengl backend implementation into the filament::backend namespace 2022-03-31 11:53:54 -07:00
Mathias Agopian 35b8146a87 move metal backend out of the metal namespace
this is to be consistent with other backends, which are all in
filament::backend.

had to rename metal::PipelineState to MetalPipelineState.
2022-03-31 11:53:54 -07:00
Mathias Agopian 091e5a33ac move Noop backend into filament::backend namespace 2022-03-31 11:53:54 -07:00
Ben Doherty ffe4b7390d Correctly prepare color grading as subpass programs (#5384) 2022-03-30 16:25:27 -07:00
Mathias Agopian 604d3e34a4 avoid an extra copy during the screen-space reflection pass
unlike for refraction, the reflection buffer is distinct from "the"
color buffer, this allows an optimization (compared to ssr) when we
generate the mipmap chain -- we can allocate the mipmaped texture
and render the SSR pass directly into its level 0. This achieved
use the framegraph's forward resource feature.
2022-03-30 15:32:52 -07:00
Mathias Agopian e116dd4aec Improve framegraph forward resource API
This add a couple methods to allow the creation and forwarding in a
single call.
2022-03-30 15:32:52 -07:00
Mathias Agopian d53614fb0a fix a framegraph crash when forwarding a subresource
the crash would happen when forwarding a subresource of a subresource,
because in this case the parent's handle would be reset to the null
handle.
2022-03-30 15:32:30 -07:00
Mathias Agopian c91e5df117 Add comment about how we calculate the viewport when upscaling 2022-03-30 08:58:50 -07:00
Philip Rideout 96574816b3 Fix 12x overallocation of memory in MorphTargetBuffer.
I noticed this while helping someone at Google understand our new API.
2022-03-30 08:24:40 -07:00
Mathias Agopian b43a609ebc rename framegraph fg2/ folder to fg/ 2022-03-29 14:38:36 -07:00
1774 changed files with 201843 additions and 87961 deletions
+4 -8
View File
@@ -50,8 +50,7 @@ jobs:
cd build/$WORKFLOW_OS && printf "y" | ./build.sh release
- name: Upload release assets
run: |
pip3 install setuptools
pip3 install PyGithub
xargs -L 1 sudo pip3 install < build/common/requirements.txt
if [ -f out/filament-release-darwin.tgz ]; then mv out/filament-release-darwin.tgz out/filament-${TAG}-mac.tgz; fi;
if [ -f out/filament-release-linux.tgz ]; then mv out/filament-release-linux.tgz out/filament-${TAG}-linux.tgz; fi;
python3 build/common/upload-assets.py ${TAG} out/*.tgz
@@ -80,8 +79,7 @@ jobs:
cd build/web && printf "y" | ./build.sh release
- name: Upload release assets
run: |
pip3 install setuptools
pip3 install PyGithub
xargs -L 1 sudo pip3 install < build/common/requirements.txt
mv out/filament-release-web.tgz out/filament-${TAG}-web.tgz
python3 build/common/upload-assets.py ${TAG} out/*.tgz
env:
@@ -123,8 +121,7 @@ jobs:
APK_KEYSTORE_PASS: ${{ secrets.APK_KEYSTORE_PASS }}
- name: Upload release assets
run: |
pip3 install setuptools
pip3 install PyGithub
xargs -L 1 sudo pip3 install < build/common/requirements.txt
mv out/filament-android-release.aar out/filament-${TAG}-android.aar
mv out/filamat-android-release.aar out/filamat-${TAG}-android.aar
mv out/filamat-android-lite-release.aar out/filamat-${TAG}-lite-android.aar
@@ -157,8 +154,7 @@ jobs:
cd build/ios && printf "y" | ./build.sh release
- name: Upload release assets
run: |
pip3 install setuptools
pip3 install PyGithub
xargs -L 1 sudo pip3 install < build/common/requirements.txt
mv out/filament-release-ios.tgz out/filament-${TAG}-ios.tgz
python3 build/common/upload-assets.py ${TAG} out/*.tgz
env:
+1 -1
View File
@@ -349,7 +349,7 @@ same version that our continuous builds use.
```
cd <your chosen parent folder for the emscripten SDK>
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.5.zip > emsdk.zip
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.9.zip > emsdk.zip
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
python ./emsdk.py install latest
python ./emsdk.py activate latest
+2 -2
View File
@@ -647,12 +647,14 @@ add_subdirectory(${LIBRARIES}/gltfio)
add_subdirectory(${LIBRARIES}/ibl)
add_subdirectory(${LIBRARIES}/iblprefilter)
add_subdirectory(${LIBRARIES}/image)
add_subdirectory(${LIBRARIES}/ktxreader)
add_subdirectory(${LIBRARIES}/math)
add_subdirectory(${LIBRARIES}/mathio)
add_subdirectory(${LIBRARIES}/utils)
add_subdirectory(${LIBRARIES}/viewer)
add_subdirectory(${FILAMENT}/filament)
add_subdirectory(${FILAMENT}/shaders)
add_subdirectory(${EXTERNAL}/basisu/tnt)
add_subdirectory(${EXTERNAL}/civetweb/tnt)
add_subdirectory(${EXTERNAL}/hat-trie/tnt)
add_subdirectory(${EXTERNAL}/imgui/tnt)
@@ -705,8 +707,6 @@ if (IS_HOST_PLATFORM)
add_subdirectory(${FILAMENT}/samples)
add_subdirectory(${EXTERNAL}/astcenc/tnt)
add_subdirectory(${EXTERNAL}/etc2comp)
add_subdirectory(${EXTERNAL}/libassimp/tnt)
add_subdirectory(${EXTERNAL}/libpng/tnt)
add_subdirectory(${EXTERNAL}/libsdl2/tnt)
+3 -2
View File
@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.20.5'
implementation 'com.google.android.filament:filament-android:1.21.3'
}
```
@@ -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:
```
pod 'Filament', '~> 1.20.5'
pod 'Filament', '~> 1.21.3'
```
### Snapshots
@@ -177,6 +177,7 @@ steps:
- [x] KHR_materials_variants
- [x] KHR_materials_volume
- [x] KHR_mesh_quantization
- [x] KHR_texture_basisu
- [x] KHR_texture_transform
+41 -5
View File
@@ -3,12 +3,48 @@
This file contains one line summaries of commits that are worthy of mentioning in release notes.
A new header is inserted each time a *tag* is created.
## v1.20.7 (currently main branch)
## v1.22.1 (currently main branch)
## v1.20.6
## v1.22.0
- gltfio: add support for KHR_materials_variants
- gltfio: add support for KHR_materials_emissive_strength
- engine: Changed UBOs layout [⚠️ **Material breakage**].
- engine: Improve effects relying on mipmapping
## v1.21.3
- Java: Renamed the `KTXLoader` Kotlin class to `KTX1Loader`. [⚠️ **API Change**].
- libs: Added `Ktx2Reader` and `BasisEncoder` to support Basis-encoded KTX2 files.
- engine: Remove deprecated `Stream` APIs, see `Texture::import()` for an alternative [⚠️ **API Change**].
- tools: Removed KTX1 compression support from mipgen. [⚠️ **API Change**].
- tools: Added support for KTX2 to mipgen.
- gltfio: Added `resetBoneMatrices()` method.
- gltfio: Introduced `TextureProvider` interface. [⚠️ **API Change**].
- gltfio: Fix progress indicator when error occurs.
- samples: Desktop and Web Suzanne samples now use KTX2 instead of KTX1.
- samples: Fix regression with sample-gltf-viewer and zip files.
## v1.21.2
- Java: Add Java binding to get skins in `FilamentAsset`.
- libs: Add libs/ktxreader [⚠️ **API Change**].
- mipgen: fixups / clarification regarding sRGB.
- WebGL: fix intermittent 'detached ArrayBuffer' errors.
## v1.21.1
- engine: Allow both screen-space refraction and screen-space reflections on the same object [⚠️ **Material breakage**].
- engine: Optimizations for screen-space reflections.
- engine: Remove `Viewport::scale()` [⚠️ **API Change**].
- engine: Fix 12x overallocation of memory in `MorphTargetBuffer`.
- Metal: Fix validation error when reading from default `SwapChain`.
## v1.21.0
- engine: OpenGL performance improvements with some drivers.
- engine: Fix incorrect shadows with some custom projection matrices.
- engine: Fix low frame rates seen with a lot of morph targets.
- gltfio: Add support for KHR_materials_variants.
- gltfio: Add support for KHR_materials_emissive_strength.
- gltfio: Java now exposes morph target names as an array for consistency [⚠️ **API Change**].
## v1.20.5
@@ -435,7 +471,7 @@ devices.
- engine: Fix RenderTarget NPE when depth is not present.
- engine: Improvements to Camera APIs. Move focus distance from DofOptions to Camera.
- engine: VSM shadows now support `shadowMultiplier`.
- java: Expose severla MaterialInstance APIs (setColorWrite, setDepthWrite, setDepthCulling) that
- java: Expose several MaterialInstance APIs (setColorWrite, setDepthWrite, setDepthCulling) that
should have been public.
- java: fix bug with Texture::setImage buffer size calculation.
+11 -1
View File
@@ -11,6 +11,9 @@
// com.google.android.filament.exclude-vulkan
// When set, support for Vulkan will be excluded.
//
// com.google.android.filament.matdbg
// When set, enables matdbg, disables shader optimizations
//
// com.google.android.filament.skip-samples
// Exclude samples from the project. Useful to speed up compilation.
//
@@ -59,6 +62,11 @@ buildscript {
.forUseAtConfigurationTime()
.isPresent()
def matdbg = providers
.gradleProperty("com.google.android.filament.matdbg")
.forUseAtConfigurationTime()
.isPresent()
def abis = ["arm64-v8a", "armeabi-v7a", "x86_64", "x86"]
def newAbis = providers
.gradleProperty("com.google.android.filament.abis")
@@ -102,7 +110,9 @@ buildscript {
"-DANDROID_PLATFORM=21",
"-DANDROID_STL=c++_static",
"-DFILAMENT_DIST_DIR=${filamentPath}".toString(),
"-DFILAMENT_SUPPORTS_VULKAN=${excludeVulkan ? 'OFF' : 'ON'}".toString()
"-DFILAMENT_SUPPORTS_VULKAN=${excludeVulkan ? 'OFF' : 'ON'}".toString(),
"-DFILAMENT_ENABLE_MATDBG=${matdbg ? 'ON' : 'OFF'}".toString(),
"-DFILAMENT_DISABLE_MATOPT=${matdbg ? 'ON' : 'OFF'}".toString()
]
ext.cppFlags = [
@@ -133,7 +133,7 @@ public class MaterialBuilder {
FADE, // material is transparent and color is alpha-pre-multiplied,
// affects specular lighting
MULTIPLY, // material darkens what's behind it
SCREN // material brightens what's behind it
SCREEN // material brightens what's behind it
}
public enum VertexDomain {
@@ -98,16 +98,6 @@ Java_com_google_android_filament_Stream_nBuilderStreamSource(JNIEnv* env,
builder->setStreamSource(env, streamSource);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Stream_nBuilderStream(JNIEnv*, jclass,
jlong nativeStreamBuilder, jlong externalTextureId) {
StreamBuilder* builder = (StreamBuilder*) nativeStreamBuilder;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
builder->builder()->stream(externalTextureId);
#pragma clang diagnostic pop
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Stream_nBuilderWidth(JNIEnv*, jclass,
jlong nativeStreamBuilder, jint width) {
@@ -143,41 +133,6 @@ Java_com_google_android_filament_Stream_nSetDimensions(JNIEnv*, jclass, jlong na
stream->setDimensions((uint32_t) width, (uint32_t) height);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Stream_nReadPixels(JNIEnv *env, jclass,
jlong nativeStream, jlong nativeEngine,
jint xoffset, jint yoffset, jint width, jint height,
jobject storage, jint remaining,
jint left, jint top, jint type, jint alignment, jint stride, jint format,
jobject handler, jobject runnable) {
Stream *stream = (Stream *) nativeStream;
Engine *engine = (Engine *) nativeEngine;
stride = stride ? stride : width;
size_t sizeInBytes = PixelBufferDescriptor::computeDataSize(
(PixelDataFormat) format, (PixelDataType) type,
(size_t) stride, (size_t) (height + top), (size_t) alignment);
AutoBuffer nioBuffer(env, storage, 0);
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
// BufferOverflowException
return -1;
}
void *buffer = nioBuffer.getData();
auto *callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
(uint32_t) stride,
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
stream->readPixels(uint32_t(xoffset), uint32_t(yoffset), uint32_t(width), uint32_t(height),
std::move(desc));
return 0;
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Stream_nGetTimestamp(JNIEnv*, jclass, jlong nativeStream) {
Stream *stream = (Stream *) nativeStream;
@@ -531,6 +531,10 @@ public class Renderer {
* Typically, this will happen after multiple calls to {@link #beginFrame},
* {@link #render}, {@link #endFrame}.</p>
* <br>
* <p>OpenGL only: if issuing a <code>readPixels</code> on a {@link RenderTarget} backed by a
* {@link Texture} that had data uploaded to it via {@link Texture#setImage}, the data returned
* from <code>readPixels</code> will be y-flipped with respect to the {@link Texture#setImage}
* call.</p>
* <p><code>readPixels</code> is intended for debugging and testing.
* It will impact performance significantly.</p>
*
@@ -103,9 +103,6 @@ public class Stream {
/** Not synchronized but copy-free. Good for video. */
NATIVE,
/** Synchronized, but GL-only and incurs copies. Good for AR on devices before API 26. */
TEXTURE_ID,
/** Synchronized, copy-free, and take a release callback. Good for AR but requires API 26+. */
ACQUIRED,
};
@@ -121,7 +118,7 @@ public class Stream {
* By default, Stream objects are {@link StreamType#ACQUIRED ACQUIRED} and must have external images pushed to them via
* {@link #setAcquiredImage}.
*
* To create a {@link StreamType#NATIVE NATIVE} or {@link StreamType#TEXTURE_ID TEXTURE_ID} stream, call one of the <pre>stream</pre> methods
* To create a {@link StreamType#NATIVE NATIVE} stream, call one of the <pre>stream</pre> methods
* on the builder.
*/
public static class Builder {
@@ -156,27 +153,6 @@ public class Stream {
throw new IllegalArgumentException("Invalid stream source: " + streamSource);
}
/**
* Creates a {@link StreamType#TEXTURE_ID TEXTURE_ID} stream. A copy stream will sample data from the supplied
* external texture and copy it into an internal private texture.
*
* <p>Currently only OpenGL external texture ids are supported.</p>
*
* @param externalTextureId An opaque texture id (typically a GLuint created with
* <code>glGenTextures()</code>) in a context shared with
* filament -- in that case this texture's target must be
* <code>GL_TEXTURE_EXTERNAL_OES.</code>
* @return This Builder, for chaining calls.
* @see Texture#setExternalStream
* @deprecated this method existed only for ARCore which doesn't need this anymore, use {@link Texture.Builder#importTexture(long)} instead.
*/
@Deprecated
@NonNull
public Builder stream(long externalTextureId) {
nBuilderStream(mNativeBuilder, externalTextureId);
return this;
}
/**
* @param width initial width of the incoming stream. Whether this value is used is
* stream dependent. On Android, it must be set when using
@@ -276,92 +252,6 @@ public class Stream {
nSetDimensions(getNativeObject(), width, height);
}
/**
* Reads back the content of the last frame of a <code>Stream</code> since the last call to
* {@link Renderer#beginFrame}.
*
* <p>The Stream must be a copy stream, which can be checked with {@link #getStreamType()}.
* This function is a no-op otherwise.</p>
*
* <pre>
*
* Stream buffer User buffer (PixelBufferDescriptor)
* +--------------------+
* | | .stride .alignment
* | | ----------------------->-->
* | | O----------------------+--+ low addresses
* | | | | | |
* | w | | | .top | |
* | <---------> | | V | |
* | +---------+ | | +---------+ | |
* | | ^ | | ======> | | | | |
* | x | h| | | |.left| | | |
* +------>| v | | +---->| | | |
* | +.........+ | | +.........+ | |
* | ^ | | | |
* | y | | +----------------------+--+ high addresses
* O------------+-------+
*
* </pre>
*
* <p>Typically readPixels() will be called after {@link Renderer#beginFrame}.</p>
*
* <p>After calling this method, the callback associated with <code>buffer</code>
* will be invoked on the main thread, indicating that the read-back has completed.
* Typically, this will happen after multiple calls to {@link Renderer#beginFrame},
* {@link Renderer#render}, {@link Renderer#endFrame}.</p>
*
* <p><code>readPixels</code> is intended for debugging and testing.
* It will impact performance significantly.</p>
*
* @param xoffset left offset of the sub-region to read back
* @param yoffset bottom offset of the sub-region to read back
* @param width width of the sub-region to read back
* @param height height of the sub-region to read back
* @param buffer client-side buffer where the read-back will be written
*
* <p>
* The following format are always supported:
* <li>{@link Texture.Format#RGBA}</li>
* <li>{@link Texture.Format#RGBA_INTEGER}</li>
* </p>
*
* <p>
* The following types are always supported:
* <li>{@link Texture.Type#UBYTE}</li>
* <li>{@link Texture.Type#UINT}</li>
* <li>{@link Texture.Type#INT}</li>
* <li>{@link Texture.Type#FLOAT}</li>
* </p>
*
* <p>Other combination of format/type may be supported. If a combination is
* not supported, this operation may fail silently. Use a DEBUG build
* to get some logs about the failure.</p>
*
* @exception BufferOverflowException if the specified parameters would result in reading
* outside of <code>buffer</code>.
*/
public void readPixels(
@IntRange(from = 0) int xoffset, @IntRange(from = 0) int yoffset,
@IntRange(from = 0) int width, @IntRange(from = 0) int height,
@NonNull Texture.PixelBufferDescriptor buffer) {
if (buffer.storage.isReadOnly()) {
throw new ReadOnlyBufferException();
}
int result = nReadPixels(getNativeObject(), mNativeEngine,
xoffset, yoffset, width, height,
buffer.storage, buffer.storage.remaining(),
buffer.left, buffer.top, buffer.type.ordinal(), buffer.alignment,
buffer.stride, buffer.format.ordinal(),
buffer.handler, buffer.callback);
if (result < 0) {
throw new BufferOverflowException();
}
}
/**
* Returns the presentation time of the currently displayed frame in nanosecond.
*
@@ -387,7 +277,6 @@ public class Stream {
private static native long nCreateBuilder();
private static native void nDestroyBuilder(long nativeStreamBuilder);
private static native void nBuilderStreamSource(long nativeStreamBuilder, Object streamSource);
private static native void nBuilderStream(long nativeStreamBuilder, long externalTextureId);
private static native void nBuilderWidth(long nativeStreamBuilder, int width);
private static native void nBuilderHeight(long nativeStreamBuilder, int height);
private static native long nBuilderBuild(long nativeStreamBuilder, long nativeEngine);
@@ -14,6 +14,10 @@ add_library(image STATIC IMPORTED)
set_target_properties(image PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libimage.a)
add_library(ktxreader STATIC IMPORTED)
set_target_properties(ktxreader PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libktxreader.a)
add_library(viewer STATIC IMPORTED)
set_target_properties(viewer PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libviewer.a)
@@ -64,5 +68,6 @@ target_link_libraries(filament-utils-jni
camutils
iblprefilter
image
ktxreader
viewer
)
@@ -20,13 +20,14 @@
#include <filament/IndirectLight.h>
#include <filament/Skybox.h>
#include <image/KtxUtility.h>
#include <ktxreader/Ktx1Reader.h>
#include "common/NioUtils.h"
using namespace filament;
using namespace filament::math;
using namespace image;
using namespace ktxreader;
jlong nCreateHDRTexture(JNIEnv* env, jclass,
jlong nativeEngine, jobject javaBuffer, jint remaining, jint internalFormat);
@@ -35,9 +36,9 @@ static jlong nCreateKTXTexture(JNIEnv* env, jclass,
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, javaBuffer, remaining);
KtxBundle* bundle = new KtxBundle((const uint8_t*) buffer.getData(), buffer.getSize());
return (jlong) ktx::createTexture(engine, *bundle, srgb, [](void* userdata) {
KtxBundle* bundle = (KtxBundle*) userdata;
Ktx1Bundle* bundle = new Ktx1Bundle((const uint8_t*) buffer.getData(), buffer.getSize());
return (jlong) Ktx1Reader::createTexture(engine, *bundle, srgb, [](void* userdata) {
Ktx1Bundle* bundle = (Ktx1Bundle*) userdata;
delete bundle;
}, bundle);
}
@@ -46,9 +47,9 @@ static jlong nCreateIndirectLight(JNIEnv* env, jclass,
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, javaBuffer, remaining);
KtxBundle* bundle = new KtxBundle((const uint8_t*) buffer.getData(), buffer.getSize());
Texture* cubemap = ktx::createTexture(engine, *bundle, srgb, [](void* userdata) {
KtxBundle* bundle = (KtxBundle*) userdata;
Ktx1Bundle* bundle = new Ktx1Bundle((const uint8_t*) buffer.getData(), buffer.getSize());
Texture* cubemap = Ktx1Reader::createTexture(engine, *bundle, srgb, [](void* userdata) {
Ktx1Bundle* bundle = (Ktx1Bundle*) userdata;
delete bundle;
}, bundle);
@@ -68,9 +69,9 @@ static jlong nCreateSkybox(JNIEnv* env, jclass,
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, javaBuffer, remaining);
KtxBundle* bundle = new KtxBundle((const uint8_t*) buffer.getData(), buffer.getSize());
Texture* cubemap = ktx::createTexture(engine, *bundle, srgb, [](void* userdata) {
KtxBundle* bundle = (KtxBundle*) userdata;
Ktx1Bundle* bundle = new Ktx1Bundle((const uint8_t*) buffer.getData(), buffer.getSize());
Texture* cubemap = Ktx1Reader::createTexture(engine, *bundle, srgb, [](void* userdata) {
Ktx1Bundle* bundle = (Ktx1Bundle*) userdata;
delete bundle;
}, bundle);
return (jlong) Skybox::Builder().environment(cubemap).showSun(true).build(*engine);
@@ -79,7 +80,7 @@ static jlong nCreateSkybox(JNIEnv* env, jclass,
static jboolean nGetSphericalHarmonics(JNIEnv* env, jclass, jobject javaBuffer, jint remaining,
jfloatArray outSphericalHarmonics_) {
AutoBuffer buffer(env, javaBuffer, remaining);
KtxBundle bundle((const uint8_t*) buffer.getData(), buffer.getSize());
Ktx1Bundle bundle((const uint8_t*) buffer.getData(), buffer.getSize());
jfloat* outSphericalHarmonics = env->GetFloatArrayElements(outSphericalHarmonics_, nullptr);
const auto success = bundle.getSphericalHarmonics(
@@ -98,8 +99,8 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
int rc;
// KTXLoader
jclass ktxloaderClass = env->FindClass("com/google/android/filament/utils/KTXLoader");
// KTX1Loader
jclass ktxloaderClass = env->FindClass("com/google/android/filament/utils/KTX1Loader");
if (ktxloaderClass == nullptr) return JNI_ERR;
static const JNINativeMethod ktxMethods[] = {
{(char*)"nCreateKTXTexture", (char*)"(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateKTXTexture)},
@@ -40,7 +40,7 @@ import com.google.android.filament.Renderer;
*
* When executing a test, clients should call tick() after each frame is rendered, which provides an
* opportunity to push settings to Filament, increment the current test index (if enough time has
* elapsed), and request an asychronous screenshot.
* elapsed), and request an asynchronous screenshot.
*
* The time to sleep between tests is configurable and can be set to zero. Automation also waits a
* specified minimum number of frames between tests.
@@ -24,12 +24,12 @@ import com.google.android.filament.Texture
import java.nio.Buffer
/**
* Utilities for consuming KTX files and producing Filament textures, IBLs, and sky boxes.
* Utilities for consuming KTX1 files and producing Filament textures, IBLs, and sky boxes.
*
* KTX is a simple container format that makes it easy to bundle miplevels and cubemap faces
* into a single file.
*/
object KTXLoader {
object KTX1Loader {
class Options {
var srgb = false
}
+18 -3
View File
@@ -11,6 +11,18 @@ add_library(dracodec STATIC IMPORTED)
set_target_properties(dracodec PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libdracodec.a)
add_library(ktxreader STATIC IMPORTED)
set_target_properties(ktxreader PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libktxreader.a)
add_library(stb STATIC IMPORTED)
set_target_properties(stb PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libstb.a)
add_library(basis_transcoder STATIC IMPORTED)
set_target_properties(basis_transcoder PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbasis_transcoder.a)
add_library(utils STATIC IMPORTED)
set_target_properties(utils PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libutils.a)
@@ -32,6 +44,7 @@ set(GLTFIO_SRCS
${GLTFIO_DIR}/include/gltfio/ResourceLoader.h
${GLTFIO_DIR}/include/gltfio/FilamentAsset.h
${GLTFIO_DIR}/include/gltfio/FilamentInstance.h
${GLTFIO_DIR}/include/gltfio/TextureProvider.h
${GLTFIO_DIR}/include/gltfio/math.h
${GLTFIO_DIR}/src/Animator.cpp
@@ -45,15 +58,16 @@ set(GLTFIO_SRCS
${GLTFIO_DIR}/src/FFilamentInstance.h
${GLTFIO_DIR}/src/FilamentInstance.cpp
${GLTFIO_DIR}/src/GltfEnums.h
${GLTFIO_DIR}/src/Ktx2Provider.cpp
${GLTFIO_DIR}/src/MaterialProvider.cpp
${GLTFIO_DIR}/src/ResourceLoader.cpp
${GLTFIO_DIR}/src/StbProvider.cpp
${GLTFIO_DIR}/src/TangentsJob.h
${GLTFIO_DIR}/src/TangentsJob.cpp
${GLTFIO_DIR}/src/UbershaderLoader.cpp
${GLTFIO_DIR}/src/Wireframe.cpp
${GLTFIO_DIR}/src/Wireframe.h
${GLTFIO_DIR}/src/upcast.h
${GLTFIO_DIR}/src/Image.cpp
src/main/cpp/Animator.cpp
src/main/cpp/AssetLoader.cpp
@@ -81,6 +95,7 @@ set(GLTFIO_INCLUDE_DIRS
../../third_party/hat-trie
../../third_party/stb
../../libs/utils/include
../../libs/ktxreader/include
)
add_library(gltfio-jni SHARED ${GLTFIO_SRCS})
@@ -90,9 +105,9 @@ set_target_properties(gltfio-jni PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_
if(GLTFIO_LITE)
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_LITE=1)
target_link_libraries(gltfio-jni filament-jni utils log gltfio_resources_lite)
target_link_libraries(gltfio-jni filament-jni utils log stb ktxreader basis_transcoder gltfio_resources_lite)
else()
target_link_libraries(gltfio-jni filament-jni utils log gltfio_resources)
target_link_libraries(gltfio-jni filament-jni utils log stb ktxreader basis_transcoder gltfio_resources)
# Enable Draco in the non-lite variant of gltfio.
target_link_libraries(gltfio-jni dracodec)
@@ -36,6 +36,12 @@ Java_com_google_android_filament_gltfio_Animator_nUpdateBoneMatrices(JNIEnv*, jc
animator->updateBoneMatrices();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_Animator_nResetBoneMatrices(JNIEnv*, jclass, jlong nativeAnimator) {
Animator* animator = (Animator*) nativeAnimator;
animator->resetBoneMatrices();
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_Animator_nGetAnimationCount(JNIEnv*, jclass, jlong nativeAnimator) {
Animator* animator = (Animator*) nativeAnimator;
@@ -201,6 +201,44 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetExtras(JNIEnv* env, jc
return val ? env->NewStringUTF(val) : nullptr;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetSkinCount(JNIEnv* , jclass,
jlong nativeAsset) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
return (jint) asset->getSkinCount();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetSkinNames(JNIEnv* env, jclass,
jlong nativeAsset, jobjectArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
jsize available = env->GetArrayLength(result);
for (int i = 0; i < available; ++i) {
const char* name = asset->getSkinNameAt(i);
if (name) {
env->SetObjectArrayElement(result, (jsize) i, env->NewStringUTF(name));
}
}
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetJointCountAt(JNIEnv* , jclass,
jlong nativeAsset, jint skinIndex) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
return (jint) asset->getJointCountAt(skinIndex);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetJointsAt(JNIEnv* env, jclass,
jlong nativeAsset, jint skinIndex, jintArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
jsize available = env->GetArrayLength(result);
Entity* entities = (Entity*) env->GetIntArrayElements(result, nullptr);
std::copy_n(asset->getJointsAt(skinIndex),
std::min(available, (jsize) asset->getJointCountAt(skinIndex)), entities);
env->ReleaseIntArrayElements(result, (jint*) entities, 0);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetAnimator(JNIEnv* , jclass,
jlong nativeAsset) {
@@ -19,6 +19,7 @@
#include <filament/Engine.h>
#include <gltfio/ResourceLoader.h>
#include <gltfio/TextureProvider.h>
#include <utils/Log.h>
@@ -114,3 +115,34 @@ Java_com_google_android_filament_gltfio_ResourceLoader_nAsyncCancelLoad(JNIEnv*,
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
loader->asyncCancelLoad();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nCreateStbProvider(JNIEnv*, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) createStbProvider(engine);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nCreateKtx2Provider(JNIEnv*, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) createKtx2Provider(engine);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nDestroyTextureProvider(JNIEnv*, jclass,
jlong nativeProvider) {
TextureProvider* provider = (TextureProvider*) nativeProvider;
delete provider;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nAddTextureProvider(JNIEnv* env, jclass,
jlong nativeLoader, jstring url, jlong nativeProvider) {
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
TextureProvider* provider = (TextureProvider*) nativeProvider;
const char* cstring = env->GetStringUTFChars(url, nullptr);
loader->addTextureProvider(cstring, provider);
env->ReleaseStringUTFChars(url, cstring);
}
@@ -66,6 +66,15 @@ public class Animator {
nUpdateBoneMatrices(getNativeObject());
}
/**
* Pass the identity matrix into all bone nodes, useful for returning to the T pose.
*
* <p>NOTE: this operation is independent of <code>animation</code>.</p>
*/
public void resetBoneMatrices() {
nResetBoneMatrices(getNativeObject());
}
/**
* Returns the number of <code>animation</code> definitions in the glTF asset.
*/
@@ -109,6 +118,7 @@ public class Animator {
private static native void nApplyAnimation(long nativeAnimator, int index, float time);
private static native void nUpdateBoneMatrices(long nativeAnimator);
private static native void nResetBoneMatrices(long nativeAnimator);
private static native int nGetAnimationCount(long nativeAnimator);
private static native float nGetAnimationDuration(long nativeAnimator, int index);
private static native String nGetAnimationName(long nativeAnimator, int index);
@@ -216,6 +216,38 @@ public class FilamentAsset {
return mAnimator;
}
/**
* Gets the skin count of this asset.
*/
public int getSkinCount() {
return nGetSkinCount(getNativeObject());
}
/**
* Gets the skin name at skin index in this asset.
*/
public @NonNull String[] getSkinNames() {
String[] result = new String[getSkinCount()];
nGetSkinNames(getNativeObject(), result);
return result;
}
/**
* Gets the joint count at skin index in this asset.
*/
public int getJointCountAt(int skinIndex) {
return nGetJointCountAt(getNativeObject(), skinIndex);
}
/**
* Gets joints at skin index in this asset.
*/
public @NonNull @Entity int[] getJointsAt(int skinIndex) {
int[] result = new int[getJointCountAt(skinIndex)];
nGetJointsAt(getNativeObject(), skinIndex, result);
return result;
}
/**
* Gets the names of all morph targets in the given entity.
*/
@@ -306,6 +338,10 @@ public class FilamentAsset {
private static native String nGetExtras(long nativeAsset, int entity);
private static native long nGetAnimator(long nativeAsset);
private static native void nApplyMaterialVariant(long nativeAsset, int variantIndex);
private static native int nGetSkinCount(long nativeAsset);
private static native void nGetSkinNames(long nativeAsset, String[] result);
private static native int nGetJointCountAt(long nativeAsset, int skinIndex);
private static native void nGetJointsAt(long nativeAsset, int skinIndex, int[] result);
private static native int nGetResourceUriCount(long nativeAsset);
private static native void nGetResourceUris(long nativeAsset, String[] result);
private static native void nReleaseSourceData(long nativeAsset);
@@ -35,6 +35,8 @@ import java.nio.Buffer;
*/
public class ResourceLoader {
private final long mNativeObject;
private final long mNativeStbProvider;
private final long mNativeKtx2Provider;
/**
* Constructs a resource loader tied to the given Filament engine.
@@ -46,6 +48,11 @@ public class ResourceLoader {
public ResourceLoader(@NonNull Engine engine) {
long nativeEngine = engine.getNativeObject();
mNativeObject = nCreateResourceLoader(nativeEngine, false, false, false);
mNativeStbProvider = nCreateStbProvider(nativeEngine);
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider);
}
/**
@@ -63,6 +70,11 @@ public class ResourceLoader {
long nativeEngine = engine.getNativeObject();
mNativeObject = nCreateResourceLoader(nativeEngine, normalizeSkinningWeights,
recomputeBoundingBoxes, ignoreBindTransform);
mNativeStbProvider = nCreateStbProvider(nativeEngine);
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider);
}
/**
@@ -70,6 +82,8 @@ public class ResourceLoader {
*/
public void destroy() {
nDestroyResourceLoader(mNativeObject);
nDestroyTextureProvider(mNativeStbProvider);
nDestroyTextureProvider(mNativeKtx2Provider);
}
/**
@@ -178,4 +192,9 @@ public class ResourceLoader {
private static native float nAsyncGetLoadProgress(long nativeLoader);
private static native void nAsyncUpdateLoad(long nativeLoader);
private static native void nAsyncCancelLoad(long nativeLoader);
private static native long nCreateStbProvider(long nativeEngine);
private static native long nCreateKtx2Provider(long nativeEngine);
private static native void nAddTextureProvider(long nativeLoader, String url, long nativeProvider);
private static native void nDestroyTextureProvider(long nativeProvider);
}
+1 -1
View File
@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.20.5
VERSION_NAME=1.21.3
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
@@ -150,12 +150,12 @@ class MainActivity : Activity() {
val scene = modelViewer.scene
val ibl = "default_env"
readCompressedAsset("envs/$ibl/${ibl}_ibl.ktx").let {
scene.indirectLight = KTXLoader.createIndirectLight(engine, it)
scene.indirectLight = KTX1Loader.createIndirectLight(engine, it)
scene.indirectLight!!.intensity = 30_000.0f
viewerContent.indirectLight = modelViewer.scene.indirectLight
}
readCompressedAsset("envs/$ibl/${ibl}_skybox.ktx").let {
scene.skybox = KTXLoader.createSkybox(engine, it)
scene.skybox = KTX1Loader.createSkybox(engine, it)
}
}
@@ -297,9 +297,10 @@ class MainActivity : Activity() {
val gltfBuffer = pathToBufferMapping[gltfPath]!!
// The gltf is often not at the root level (e.g. if a folder is zipped) so
// we need to extract its path in order to resolve the embedded uri strings.
var prefix = URI(gltfPath!!).resolve("..")
// In a zip file, the gltf file might be in the same folder as resources, or in a different
// folder. It is crucial to test against both of these cases. In any case, the resource
// paths are all specified relative to the location of the gltf file.
var prefix = URI(gltfPath!!).resolve(".")
withContext(Dispatchers.Main) {
if (gltfPath!!.endsWith(".glb")) {
@@ -308,7 +309,7 @@ class MainActivity : Activity() {
modelViewer.loadModelGltf(gltfBuffer) { uri ->
val path = prefix.resolve(uri).toString()
if (!pathToBufferMapping.contains(path)) {
Log.e(TAG, "Could not find '$uri' in zip using prefix '$prefix'")
Log.e(TAG, "Could not find '$uri' in zip using prefix '$prefix' and base path '${gltfPath!!}'")
setStatusText("Zip is missing $path")
}
pathToBufferMapping[path]
@@ -79,8 +79,6 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
// Performs the rendering and schedules new frames
private val frameScheduler = FrameCallback()
private var externalTextureID: Int = 0
@RequiresApi(30)
class Api30Impl {
companion object {
@@ -103,8 +101,6 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
setupView()
setupScene()
externalTextureID = createExternalTexture()
@Suppress("deprecation")
val display = if (Build.VERSION.SDK_INT >= 30) {
Api30Impl.getDisplay(this)
@@ -112,7 +108,7 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
windowManager.defaultDisplay!!
}
streamHelper = StreamHelper(engine, materialInstance, display, externalTextureID)
streamHelper = StreamHelper(engine, materialInstance, display)
this.title = streamHelper.getTestName()
}
@@ -445,31 +441,4 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
check(EGL14.eglMakeCurrent(display, surface, surface, context)) { "Error making GL context." }
return context
}
private fun createExternalTexture(): Int {
val textures = IntArray(1)
GLES30.glGenTextures(1, textures, 0)
val result = textures[0]
val textureTarget = GLES11Ext.GL_TEXTURE_EXTERNAL_OES
GLES30.glBindTexture(textureTarget, result)
GLES30.glTexParameteri(textureTarget, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE)
GLES30.glTexParameteri(textureTarget, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE)
GLES30.glTexParameteri(textureTarget, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST)
GLES30.glTexParameteri(textureTarget, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_NEAREST)
if (!GLES30.glIsTexture(result)) {
throw RuntimeException("OpenGL error: $result is an invalid texture.")
}
val error = GLES30.glGetError()
if (error != GLES30.GL_NO_ERROR) {
val errorString = GLU.gluErrorString(error)
throw RuntimeException("OpenGL error: $errorString!")
}
return result
}
}
@@ -37,7 +37,6 @@ class StreamHelper(
private val filamentEngine: Engine,
private val filamentMaterial: MaterialInstance,
private val display: Display,
private val externalTextureId: Int
) {
/**
* The StreamSource configures the source data for the texture.
@@ -51,7 +50,6 @@ class StreamHelper(
*/
enum class StreamSource {
CANVAS_STREAM_NATIVE, // copy-free but does not guarantee synchronization
CANVAS_STREAM_TEXID, // synchronized but incurs a copy
CANVAS_STREAM_ACQUIRED, // synchronized and copy-free
}
@@ -127,10 +125,6 @@ class StreamHelper(
surface.unlockCanvasAndPost(canvas)
if (streamSource == StreamSource.CANVAS_STREAM_TEXID) {
surfaceTexture!!.updateTexImage()
}
if (streamSource == StreamSource.CANVAS_STREAM_ACQUIRED) {
val image = imageReader!!.acquireLatestImage()
filamentStream!!.setAcquiredImage(
@@ -146,7 +140,7 @@ class StreamHelper(
fun nextTest() {
stopTest()
streamSource = StreamSource.values()[(streamSource.ordinal + 1) % 3]
streamSource = StreamSource.values()[(streamSource.ordinal + 1) % StreamSource.values().size]
startTest()
}
@@ -213,23 +207,6 @@ class StreamHelper(
filamentTexture.setExternalStream(filamentEngine, filamentStream!!)
}
if (streamSource == StreamSource.CANVAS_STREAM_TEXID) {
// Create the Android surface that will hold the canvas image.
surfaceTexture = SurfaceTexture(externalTextureId)
surfaceTexture!!.setDefaultBufferSize(resolution.width, resolution.height)
canvasSurface = Surface(surfaceTexture)
// Create the Filament Stream object that gets bound to the Texture.
filamentStream = Stream.Builder()
.stream(externalTextureId.toLong())
.width(resolution.width)
.height(resolution.height)
.build(filamentEngine)
filamentTexture.setExternalStream(filamentEngine, filamentStream!!)
}
if (streamSource == StreamSource.CANVAS_STREAM_ACQUIRED) {
filamentStream = Stream.Builder()
.width(resolution.width)
Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

+10 -6
View File
@@ -98,9 +98,9 @@ function print_matdbg_help {
echo ""
echo "FOR ANDROID BUILDS:"
echo ""
echo "1) The most reliable way to enable matdbg is to bypass Gradle and"
echo " directly modify the appropriate two lines in the following file:"
echo " ./android/filament-android/CMakeLists.txt"
echo "1) For Android Studio builds, make sure to set:"
echo " -Pcom.google.android.filament.matdbg"
echo " option in Preferences > Build > Compiler > Command line options."
echo ""
echo "2) The port number is hardcoded to 8081 so you will need to do:"
echo " adb forward tcp:8081 tcp:8081"
@@ -156,6 +156,7 @@ VULKAN_ANDROID_GRADLE_OPTION=""
SWIFTSHADER_OPTION="-DFILAMENT_USE_SWIFTSHADER=OFF"
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=OFF"
MATDBG_GRADLE_OPTION=""
IOS_BUILD_SIMULATOR=false
BUILD_UNIVERSAL_LIBRARIES=false
@@ -303,7 +304,7 @@ function build_webgl_with_target {
}
function build_webgl {
# For the host tools, supress install and always use Release.
# For the host tools, suppress install and always use Release.
local old_install_command=${INSTALL_COMMAND}; INSTALL_COMMAND=
local old_issue_debug_build=${ISSUE_DEBUG_BUILD}; ISSUE_DEBUG_BUILD=false
local old_issue_release_build=${ISSUE_RELEASE_BUILD}; ISSUE_RELEASE_BUILD=true
@@ -402,7 +403,7 @@ function ensure_android_build {
function build_android {
ensure_android_build
# Supress intermediate desktop tools install
# Suppress intermediate desktop tools install
local old_install_command=${INSTALL_COMMAND}
INSTALL_COMMAND=
@@ -456,6 +457,7 @@ function build_android {
-Pcom.google.android.filament.dist-dir=../out/android-debug/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${VULKAN_ANDROID_GRADLE_OPTION} \
${MATDBG_GRADLE_OPTION} \
:filament-android:assembleDebug \
:gltfio-android:assembleDebug \
:filament-utils-android:assembleDebug
@@ -504,6 +506,7 @@ function build_android {
-Pcom.google.android.filament.dist-dir=../out/android-release/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${VULKAN_ANDROID_GRADLE_OPTION} \
${MATDBG_GRADLE_OPTION} \
:filament-android:assembleRelease \
:gltfio-android:assembleRelease \
:filament-utils-android:assembleRelease
@@ -598,7 +601,7 @@ function archive_ios {
}
function build_ios {
# Supress intermediate desktop tools install
# Suppress intermediate desktop tools install
local old_install_command=${INSTALL_COMMAND}
INSTALL_COMMAND=
@@ -754,6 +757,7 @@ while getopts ":hacCfijmp:q:uvslwtdk:" opt; do
d)
PRINT_MATDBG_HELP=true
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=ON, -DFILAMENT_DISABLE_MATOPT=ON, -DFILAMENT_BUILD_FILAMAT=ON"
MATDBG_GRADLE_OPTION="-Pcom.google.android.filament.matdbg"
;;
f)
ISSUE_CMAKE_ALWAYS=true
+14
View File
@@ -0,0 +1,14 @@
setuptools==40.6.2
wheel==0.37.1
certifi==2021.10.8
cffi==1.15.0
charset-normalizer==2.0.12
Deprecated==1.2.13
idna==3.3
pycparser==2.21
PyGithub==1.55
PyJWT==2.3.0
PyNaCl==1.5.0
requests==2.27.1
urllib3==1.26.9
wrapt==1.14.0
+1
View File
@@ -11,3 +11,4 @@ tools/cmgen/test_cmgen compare
tools/glslminifier/test_glslminifier
libs/filameshio/test_filameshio
libs/camutils/test_camutils
libs/ktxreader/test_ktxreader
+19
View File
@@ -12,6 +12,25 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# requirements.txt created via:
#
# pip3 install virtualenv
# python3 -m venv env
# pip3 install PyGithub
# pip3 install wheel
# --all includes wheel and setuputils, which is needed for GitHub Actions
# pip3 freeze --all > requirements.txt
# Manually move 'setuptools' and 'wheel' lines to the beginning of the file.
# Manually remove the 'pip' line.
#
# Requirements are installed in GitHub Actions via:
# xargs -L 1 sudo pip3 install < build/common/requirements.txt
# xargs must be used because the ordering of the dependencies matters (namely, setuptools).
# sudo must be used to uninstall non-matching versions of packages.
# pip is removed to avoid conflicts with the pre-installed pip version on Actions.
# This technique does not work with Windows, unfortunately.
from github import Github
import os, sys
+1 -1
View File
@@ -17,7 +17,7 @@ export PATH="$PWD:$PATH"
# npm install -g typescript
# Install emscripten.
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.5.zip > emsdk.zip
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.9.zip > emsdk.zip
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
./emsdk install latest
./emsdk activate latest
+1 -1
View File
@@ -2169,7 +2169,7 @@ type aliases:
Name | Type | Description
:-----------------------------------|:--------:|:------------------------------------
**getResolution()** | float4 | Resolution of the view in pixels: `width`, `height`, `1 / width`, `1 / height`
**getResolution()** | float4 | Dimensions of the view's effective viewport in pixels: `width`, `height`, `1 / width`, `1 / height`. This might be different from `View::getViewport()` for instance because of added rendering guard-bands. This can be used in conjunction with `getNormalizedViewportCoord()` to generate pixel coordinates.
**getWorldCameraPosition()** | float3 | Position of the camera/eye in world space
**getWorldOffset()** | float3 | The shift required to obtain API-level world space
**getTime()** | float | Current time as a remainder of 1 second. Yields a value between 0 and 1
+1 -1
View File
@@ -12,7 +12,7 @@
</head>
<body>
<canvas></canvas>
<script src="//unpkg.com/filament@1.15.0/filament.js"></script>
<script src="filament.js"></script>
<script src="//unpkg.com/gl-matrix@2.8.1"></script>
<script src="//unpkg.com/gltumble"></script>
<script src="tutorial_redball.js"></script>
+1 -1
View File
@@ -12,7 +12,7 @@
</head>
<body>
<canvas></canvas>
<script src="//unpkg.com/filament@1.15.0/filament.js"></script>
<script src="filament.js"></script>
<script src="//unpkg.com/gl-matrix@2.8.1"></script>
<script src="//unpkg.com/gltumble"></script>
<script src="tutorial_suzanne.js"></script>
+1 -1
View File
@@ -12,7 +12,7 @@
</head>
<body>
<canvas></canvas>
<script src="//unpkg.com/filament@1.15.0/filament.js"></script>
<script src="filament.js"></script>
<script src="//unpkg.com/gl-matrix@2.8.1"></script>
<script src="//unpkg.com/gltumble"></script>
<script src="tutorial_triangle.js"></script>
+10 -6
View File
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+20 -13
View File
@@ -64,7 +64,7 @@
<td align="left">Array of 16-bit or 32-bit unsigned integers consumed by the GPU.</td>
</tr>
<tr>
<td align="left"><a href="#KtxBundle">KtxBundle</a></td>
<td align="left"><a href="#Ktx1Bundle">Ktx1Bundle</a></td>
<td align="left">In-memory representation of a KTX file.</td>
</tr>
<tr>
@@ -583,6 +583,11 @@
<li><em>overrides</em> Dictionary with one or more of the following properties: enabled, sampleCount, customResolve.</li>
</ul>
</li>
<li><strong>engine.setScreenSpaceReflectionsOptions(overrides)</strong>
<ul>
<li><em>overrides</em> Dictionary with one or more of the following properties: thickness, bias, maxDistance, stride, enabled.</li>
</ul>
</li>
<li><strong>engine.setShadowOptions(instance, overrides)</strong>
<ul>
<li><em>instance</em> Instance of a light component obtained from <code>getInstance</code>.</li>
@@ -662,63 +667,63 @@ as quaternions.</li>
</ul>
</div>
<div class='classdoc'>
<h2>class <a id='KtxBundle' href='#KtxBundle'>KtxBundle</a></h2>
<h2>class <a id='Ktx1Bundle' href='#Ktx1Bundle'>Ktx1Bundle</a></h2>
<p>In-memory representation of a KTX file.</p>
<ul>
<li><strong>ktxBundle.getArrayLength()</strong>
<li><strong>ktx1Bundle.getArrayLength()</strong>
<ul>
<li>Obtains length of the texture array.</li>
<li><em>returns</em> The number of elements in the texture array</li>
</ul>
</li>
<li><strong>ktxBundle.getCompressedPixelDataType()</strong>
<li><strong>ktx1Bundle.getCompressedPixelDataType()</strong>
<ul>
<li><em>returns</em> <a href="#CompressedPixelDataType">CompressedPixelDataType</a></li>
</ul>
</li>
<li><strong>ktxBundle.getInternalFormat(srgb)</strong>
<li><strong>ktx1Bundle.getInternalFormat(srgb)</strong>
<ul>
<li><em>srgb</em> boolean that forces the resulting format to SRGB if possible.</li>
<li><em>returns</em> <a href="#Texture%24InternalFormat">Texture$InternalFormat</a></li>
</ul>
</li>
<li><strong>ktxBundle.getMetadata(key)</strong>
<li><strong>ktx1Bundle.getMetadata(key)</strong>
<ul>
<li>Obtains arbitrary metadata from the KTX file.</li>
<li><em>key</em> string</li>
<li><em>returns</em> string</li>
</ul>
</li>
<li><strong>ktxBundle.getPixelDataFormat()</strong>
<li><strong>ktx1Bundle.getPixelDataFormat()</strong>
<ul>
<li><em>returns</em> <a href="#PixelDataFormat">PixelDataFormat</a></li>
</ul>
</li>
<li><strong>ktxBundle.getPixelDataType()</strong>
<li><strong>ktx1Bundle.getPixelDataType()</strong>
<ul>
<li><em>returns</em> <a href="#PixelDataType">PixelDataType</a></li>
</ul>
</li>
<li><strong>ktxBundle.info()</strong>
<li><strong>ktx1Bundle.info()</strong>
<ul>
<li>Obtains properties of the KTX header.</li>
<li><em>returns</em> The <a href="#KtxInfo">KtxInfo</a> property accessor object.</li>
</ul>
</li>
<li><strong>ktxBundle.info()</strong>
<li><strong>ktx1Bundle.info()</strong>
<ul>
<li>Obtains properties of the KTX header.</li>
<li><em>returns</em> The <a href="#KtxInfo">KtxInfo</a> property accessor object.</li>
</ul>
</li>
<li><strong>ktxBundle.isCompressed()</strong>
<li><strong>ktx1Bundle.isCompressed()</strong>
<ul>
<li><em>returns</em> boolean</li>
</ul>
</li>
</ul>
<p>Most clients should use one of the <code>create*FromKtx</code> utility methods in the JavaScript <a href="#Engine">Engine</a>
wrapper rather than interacting with <code>KtxBundle</code> directly.</p>
wrapper rather than interacting with <code>Ktx1Bundle</code> directly.</p>
</div>
<div class='classdoc'>
<h2>class <a id='KtxInfo' href='#KtxInfo'>KtxInfo</a></h2>
@@ -743,7 +748,7 @@ wrapper rather than interacting with <code>KtxBundle</code> directly.</p>
</ul>
</li>
</ul>
<p>For example, <code>ktxbundle.info().pixelWidth</code>. See the
<p>For example, <code>Ktx1Bundle.info().pixelWidth</code>. See the
<a href="https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/">KTX spec</a> for the list of
properties.</p>
</div>
@@ -1267,7 +1272,9 @@ This defines the following functions:</p>
<ul>
<li>POINTS</li>
<li>LINES</li>
<li>LINE_STRIP</li>
<li>TRIANGLES</li>
<li>TRIANGLE_STRIP</li>
<li>NONE</li>
</ul>
</div>
Binary file not shown.
Binary file not shown.
+18 -16
View File
@@ -12,7 +12,9 @@ textures.</p>
<a href="tutorial_triangle.html">previous tutorial</a>. Change the last script tag from <code>triangle.js</code> to <code>redball.js</code>.</p>
<p>Next you'll need to get a couple command-line tools: <code>matc</code> and <code>cmgen</code>. You can find these in the
appropriate <a href="//github.com/google/filament/releases">Filament release</a>. You should choose the
archive that corresponds to your development machine rather than the one for web.</p>
archive that corresponds to your development machine rather than the one for web, and the version
that matches the <code>unpkg.com/filament@x.x.x</code> url in the script tag of <code>redball.html</code> (you may check
out the last available release of <a href="https://www.npmjs.com/package/filament">filament on npm</a>).</p>
<h2>Define plastic material</h2>
<p>The <code>matc</code> tool consumes a text file containing a high-level description of a PBR material, and
produces a binary material package that contains shader code and associated metadata. For more
@@ -60,12 +62,12 @@ IBL KTX contains these coefficients in its metadata.</p>
<h2>Create JavaScript</h2>
<p>Next, create <code>redball.js</code> with the following content.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> environ <span style="color: #666666">=</span> <span style="color: #BA2121">&#39;pillars_2k&#39;</span>;
<span style="color: #008000; font-weight: bold">const</span> ibl_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> sky_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> ibl_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> sky_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> filamat_url <span style="color: #666666">=</span> <span style="color: #BA2121">&#39;plastic.filamat&#39;</span>
Filament.init([ filamat_url, ibl_url, sky_url ], () =&gt; {
<span style="color: #408080; font-style: italic">// Create some global aliases to enums for convenience.</span>
<span style="color: #3D7B7B; font-style: italic">// Create some global aliases to enums for convenience.</span>
<span style="color: #008000">window</span>.VertexAttribute <span style="color: #666666">=</span> Filament.VertexAttribute;
<span style="color: #008000">window</span>.AttributeType <span style="color: #666666">=</span> Filament.VertexBuffer$AttributeType;
<span style="color: #008000">window</span>.PrimitiveType <span style="color: #666666">=</span> Filament.RenderableManager$PrimitiveType;
@@ -73,7 +75,7 @@ Filament.init([ filamat_url, ibl_url, sky_url ], () =&gt; {
<span style="color: #008000">window</span>.Fov <span style="color: #666666">=</span> Filament.Camera$Fov;
<span style="color: #008000">window</span>.LightType <span style="color: #666666">=</span> Filament.LightManager$Type;
<span style="color: #408080; font-style: italic">// Obtain the canvas DOM object and pass it to the App.</span>
<span style="color: #3D7B7B; font-style: italic">// Obtain the canvas DOM object and pass it to the App.</span>
<span style="color: #008000; font-weight: bold">const</span> canvas <span style="color: #666666">=</span> <span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">&#39;canvas&#39;</span>)[<span style="color: #666666">0</span>];
<span style="color: #008000">window</span>.app <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> App(canvas);
} );
@@ -84,11 +86,11 @@ Filament.init([ filamat_url, ibl_url, sky_url ], () =&gt; {
<span style="color: #008000; font-weight: bold">const</span> engine <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine <span style="color: #666666">=</span> Filament.Engine.create(canvas);
<span style="color: #008000; font-weight: bold">const</span> scene <span style="color: #666666">=</span> engine.createScene();
<span style="color: #408080; font-style: italic">// TODO: create material</span>
<span style="color: #408080; font-style: italic">// TODO: create sphere</span>
<span style="color: #408080; font-style: italic">// TODO: create lights</span>
<span style="color: #408080; font-style: italic">// TODO: create IBL</span>
<span style="color: #408080; font-style: italic">// TODO: create skybox</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: create material</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: create sphere</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: create lights</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: create IBL</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: create skybox</span>
<span style="color: #008000; font-weight: bold">this</span>.swapChain <span style="color: #666666">=</span> engine.createSwapChain();
<span style="color: #008000; font-weight: bold">this</span>.renderer <span style="color: #666666">=</span> engine.createRenderer();
@@ -209,9 +211,9 @@ following (don't type this out, there's an easier way).</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> format <span style="color: #666666">=</span> Filament.PixelDataFormat.RGB;
<span style="color: #008000; font-weight: bold">const</span> datatype <span style="color: #666666">=</span> Filament.PixelDataType.UINT_10F_11F_11F_REV;
<span style="color: #408080; font-style: italic">// Create a Texture object for the mipmapped cubemap.</span>
<span style="color: #3D7B7B; font-style: italic">// Create a Texture object for the mipmapped cubemap.</span>
<span style="color: #008000; font-weight: bold">const</span> ibl_package <span style="color: #666666">=</span> Filament.Buffer(Filament.assets[ibl_url]);
<span style="color: #008000; font-weight: bold">const</span> iblktx <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.KtxBundle(ibl_package);
<span style="color: #008000; font-weight: bold">const</span> iblktx <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.Ktx1Bundle(ibl_package);
<span style="color: #008000; font-weight: bold">const</span> ibltex <span style="color: #666666">=</span> Filament.Texture.Builder()
.width(iblktx.info().pixelWidth)
@@ -227,11 +229,11 @@ following (don't type this out, there's an easier way).</p>
ibltex.setImageCube(engine, level, pixelbuffer);
}
<span style="color: #408080; font-style: italic">// Parse the spherical harmonics metadata.</span>
<span style="color: #3D7B7B; font-style: italic">// Parse the spherical harmonics metadata.</span>
<span style="color: #008000; font-weight: bold">const</span> shstring <span style="color: #666666">=</span> iblktx.getMetadata(<span style="color: #BA2121">&#39;sh&#39;</span>);
<span style="color: #008000; font-weight: bold">const</span> shfloats <span style="color: #666666">=</span> shstring.split(<span style="color: #BB6688">/\s/</span>, <span style="color: #666666">9</span> <span style="color: #666666">*</span> <span style="color: #666666">3</span>).map(<span style="color: #008000">parseFloat</span>);
<span style="color: #008000; font-weight: bold">const</span> shfloats <span style="color: #666666">=</span> shstring.split(<span style="color: #A45A77">/\s/</span>, <span style="color: #666666">9</span> <span style="color: #666666">*</span> <span style="color: #666666">3</span>).map(<span style="color: #008000">parseFloat</span>);
<span style="color: #408080; font-style: italic">// Build the IBL object and insert it into the scene.</span>
<span style="color: #3D7B7B; font-style: italic">// Build the IBL object and insert it into the scene.</span>
<span style="color: #008000; font-weight: bold">const</span> indirectLight <span style="color: #666666">=</span> Filament.IndirectLight.Builder()
.reflections(ibltex)
.irradianceSh(<span style="color: #666666">3</span>, shfloats)
@@ -253,7 +255,7 @@ scene.setIndirectLight(indirectLight);
Without a skybox, the reflections on the ball are not representative of its surroundings.
Here's one way to create a texture for the skybox:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> sky_package <span style="color: #666666">=</span> Filament.Buffer(Filament.assets[sky_url]);
<span style="color: #008000; font-weight: bold">const</span> skyktx <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.KtxBundle(sky_package);
<span style="color: #008000; font-weight: bold">const</span> skyktx <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.Ktx1Bundle(sky_package);
<span style="color: #008000; font-weight: bold">const</span> skytex <span style="color: #666666">=</span> Filament.Texture.Builder()
.width(skyktx.info().pixelWidth)
.height(skyktx.info().pixelHeight)
+21 -21
View File
@@ -22,25 +22,25 @@ converting <a href="https://github.com/google/filament/blob/main/assets/models/m
<p>Next, let's create mipmapped KTX files using filament's <code>mipgen</code> tool. We'll create compressed and
non-compressed variants for each texture, since not all platforms support the same compression
formats. First copy over the PNG files from the <a href="https://github.com/google/filament/blob/main/assets/models/monkey">monkey folder</a>, then do:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #408080; font-style: italic"># Create mipmaps for base color and two compressed variants.</span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic"># Create mipmaps for base color and two compressed variants.</span>
mipgen albedo.png albedo.ktx
mipgen --compression<span style="color: #666666">=</span>astc_fast_ldr_4x4 albedo.png albedo_astc.ktx
mipgen --compression<span style="color: #666666">=</span>s3tc_rgb_dxt1 albedo.png albedo_s3tc_srgb.ktx
<span style="color: #408080; font-style: italic"># Create mipmaps for the normal map and a compressed variant.</span>
<span style="color: #3D7B7B; font-style: italic"># Create mipmaps for the normal map and a compressed variant.</span>
mipgen --strip-alpha --kernel<span style="color: #666666">=</span>NORMALS --linear normal.png normal.ktx
mipgen --strip-alpha --kernel<span style="color: #666666">=</span>NORMALS --linear --compression<span style="color: #666666">=</span>etc_rgb8_normalxyz_40 <span style="color: #BB6622; font-weight: bold">\</span>
mipgen --strip-alpha --kernel<span style="color: #666666">=</span>NORMALS --linear --compression<span style="color: #666666">=</span>etc_rgb8_normalxyz_40 <span style="color: #AA5D1F; font-weight: bold">\</span>
normal.png normal_etc.ktx
<span style="color: #408080; font-style: italic"># Create mipmaps for the single-component roughness map and a compressed variant.</span>
<span style="color: #3D7B7B; font-style: italic"># Create mipmaps for the single-component roughness map and a compressed variant.</span>
mipgen --grayscale roughness.png roughness.ktx
mipgen --grayscale --compression<span style="color: #666666">=</span>etc_r11_numeric_40 roughness.png roughness_etc.ktx
<span style="color: #408080; font-style: italic"># Create mipmaps for the single-component metallic map and a compressed variant.</span>
<span style="color: #3D7B7B; font-style: italic"># Create mipmaps for the single-component metallic map and a compressed variant.</span>
mipgen --grayscale metallic.png metallic.ktx
mipgen --grayscale --compression<span style="color: #666666">=</span>etc_r11_numeric_40 metallic.png metallic_etc.ktx
<span style="color: #408080; font-style: italic"># Create mipmaps for the single-component occlusion map and a compressed variant.</span>
<span style="color: #3D7B7B; font-style: italic"># Create mipmaps for the single-component occlusion map and a compressed variant.</span>
mipgen --grayscale ao.png ao.ktx
mipgen --grayscale --compression<span style="color: #666666">=</span>etc_r11_numeric_40 ao.png ao_etc.ktx
</pre></div>
@@ -101,7 +101,7 @@ materials, consult the official document describing the <a href="https://google.
<p>Create a text file called <code>suzanne.html</code> and copy over the HTML that we used in the <a href="tutorial_redball.html">previous
tutorial</a>. Change the last script tag from <code>redball.js</code> to <code>suzanne.js</code>. Next, create <code>suzanne.js</code>
with the following content.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #408080; font-style: italic">// TODO: declare asset URLs</span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic">// TODO: declare asset URLs</span>
Filament.init([ filamat_url, filamesh_url, sky_small_url, ibl_url ], () =&gt; {
<span style="color: #008000">window</span>.app <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> App(<span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">&#39;canvas&#39;</span>)[<span style="color: #666666">0</span>]);
@@ -119,9 +119,9 @@ Filament.init([ filamat_url, filamesh_url, sky_small_url, ibl_url ], () =&gt; {
<span style="color: #008000; font-weight: bold">const</span> filamesh <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.loadFilamesh(filamesh_url, <span style="color: #008000; font-weight: bold">this</span>.matinstance);
<span style="color: #008000; font-weight: bold">this</span>.suzanne <span style="color: #666666">=</span> filamesh.renderable;
<span style="color: #408080; font-style: italic">// TODO: create sky box and IBL</span>
<span style="color: #408080; font-style: italic">// TODO: initialize gltumble</span>
<span style="color: #408080; font-style: italic">// TODO: fetch larger assets</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: create sky box and IBL</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: initialize gltumble</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: fetch larger assets</span>
<span style="color: #008000; font-weight: bold">this</span>.swapChain <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createSwapChain();
<span style="color: #008000; font-weight: bold">this</span>.renderer <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createRenderer();
@@ -141,7 +141,7 @@ Filament.init([ filamat_url, filamesh_url, sky_small_url, ibl_url ], () =&gt; {
}
render() {
<span style="color: #408080; font-style: italic">// TODO: apply gltumble matrix</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: apply gltumble matrix</span>
<span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain, <span style="color: #008000; font-weight: bold">this</span>.view);
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
}
@@ -176,14 +176,14 @@ last resort. Go ahead and replace the <strong>declare asset URLs</strong> commen
<span style="color: #008000; font-weight: bold">const</span> texture_suffix <span style="color: #666666">=</span> Filament.getSupportedFormatSuffix(<span style="color: #BA2121">&#39;etc&#39;</span>);
<span style="color: #008000; font-weight: bold">const</span> environ <span style="color: #666666">=</span> <span style="color: #BA2121">&#39;venetian_crossroads_2k&#39;</span>
<span style="color: #008000; font-weight: bold">const</span> ibl_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> sky_small_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">_skybox_tiny.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> sky_large_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> albedo_url <span style="color: #666666">=</span> <span style="color: #BA2121">`albedo</span><span style="color: #BB6688; font-weight: bold">${</span>albedo_suffix<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> ao_url <span style="color: #666666">=</span> <span style="color: #BA2121">`ao</span><span style="color: #BB6688; font-weight: bold">${</span>texture_suffix<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> metallic_url <span style="color: #666666">=</span> <span style="color: #BA2121">`metallic</span><span style="color: #BB6688; font-weight: bold">${</span>texture_suffix<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> normal_url <span style="color: #666666">=</span> <span style="color: #BA2121">`normal</span><span style="color: #BB6688; font-weight: bold">${</span>texture_suffix<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> roughness_url <span style="color: #666666">=</span> <span style="color: #BA2121">`roughness</span><span style="color: #BB6688; font-weight: bold">${</span>texture_suffix<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> ibl_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> sky_small_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox_tiny.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> sky_large_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> albedo_url <span style="color: #666666">=</span> <span style="color: #BA2121">`albedo</span><span style="color: #A45A77; font-weight: bold">${</span>albedo_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> ao_url <span style="color: #666666">=</span> <span style="color: #BA2121">`ao</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> metallic_url <span style="color: #666666">=</span> <span style="color: #BA2121">`metallic</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> normal_url <span style="color: #666666">=</span> <span style="color: #BA2121">`normal</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> roughness_url <span style="color: #666666">=</span> <span style="color: #BA2121">`roughness</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span> filamat_url <span style="color: #666666">=</span> <span style="color: #BA2121">&#39;textured.filamat&#39;</span>;
<span style="color: #008000; font-weight: bold">const</span> filamesh_url <span style="color: #666666">=</span> <span style="color: #BA2121">&#39;suzanne.filamesh&#39;</span>;
</pre></div>
@@ -224,7 +224,7 @@ was created in the app constructor.</p>
<span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;normal&#39;</span>, normal, sampler);
<span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;ao&#39;</span>, ao, sampler);
<span style="color: #408080; font-style: italic">// Replace low-res skybox with high-res skybox.</span>
<span style="color: #3D7B7B; font-style: italic">// Replace low-res skybox with high-res skybox.</span>
<span style="color: #008000; font-weight: bold">this</span>.engine.destroySkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);
<span style="color: #008000; font-weight: bold">this</span>.skybox <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createSkyFromKtx(sky_large_url);
<span style="color: #008000; font-weight: bold">this</span>.scene.setSkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);
@@ -236,7 +236,7 @@ was created in the app constructor.</p>
<h2>Introduce trackball rotation</h2>
<p>Add the following script tag to your HTML file. This imports a small third-party library that
listens for drag events and computes a rotation matrix.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>&lt;<span style="color: #008000; font-weight: bold">script</span> <span style="color: #7D9029">src</span><span style="color: #666666">=</span><span style="color: #BA2121">&quot;//unpkg.com/gltumble&quot;</span>&gt;&lt;/<span style="color: #008000; font-weight: bold">script</span>&gt;
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>&lt;<span style="color: #008000; font-weight: bold">script</span> <span style="color: #687822">src</span><span style="color: #666666">=</span><span style="color: #BA2121">&quot;//unpkg.com/gltumble&quot;</span>&gt;&lt;/<span style="color: #008000; font-weight: bold">script</span>&gt;
</pre></div>
<p>Next, replace the <strong>initialize gltumble</strong> and <strong>apply gltumble matrix</strong> comments with the following
+22 -22
View File
@@ -16,22 +16,22 @@ subsequent code blocks.</p>
<h2>Start your project</h2>
<p>First, create a text file called <code>triangle.html</code> and fill it with the following HTML. This creates
a mobile-friendly page with a full-screen canvas.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #BC7A00">&lt;!DOCTYPE html&gt;</span>
&lt;<span style="color: #008000; font-weight: bold">html</span> <span style="color: #7D9029">lang</span><span style="color: #666666">=</span><span style="color: #BA2121">&quot;en&quot;</span>&gt;
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #9C6500">&lt;!DOCTYPE html&gt;</span>
&lt;<span style="color: #008000; font-weight: bold">html</span> <span style="color: #687822">lang</span><span style="color: #666666">=</span><span style="color: #BA2121">&quot;en&quot;</span>&gt;
&lt;<span style="color: #008000; font-weight: bold">head</span>&gt;
&lt;<span style="color: #008000; font-weight: bold">title</span>&gt;Filament Tutorial&lt;/<span style="color: #008000; font-weight: bold">title</span>&gt;
&lt;<span style="color: #008000; font-weight: bold">meta</span> <span style="color: #7D9029">charset</span><span style="color: #666666">=</span><span style="color: #BA2121">&quot;utf-8&quot;</span>&gt;
&lt;<span style="color: #008000; font-weight: bold">meta</span> <span style="color: #7D9029">name</span><span style="color: #666666">=</span><span style="color: #BA2121">&quot;viewport&quot;</span> <span style="color: #7D9029">content</span><span style="color: #666666">=</span><span style="color: #BA2121">&quot;width=device-width,user-scalable=no,initial-scale=1&quot;</span>&gt;
&lt;<span style="color: #008000; font-weight: bold">style</span>&gt;
<span style="color: #008000; font-weight: bold">body</span> { <span style="color: #008000; font-weight: bold">margin</span>: <span style="color: #666666">0</span>; <span style="color: #008000; font-weight: bold">overflow</span>: <span style="color: #008000; font-weight: bold">hidden</span>; }
<span style="color: #008000; font-weight: bold">canvas</span> { touch-action: <span style="color: #008000; font-weight: bold">none</span>; <span style="color: #008000; font-weight: bold">width</span>: <span style="color: #666666">100</span><span style="color: #B00040">%</span>; <span style="color: #008000; font-weight: bold">height</span>: <span style="color: #666666">100</span><span style="color: #B00040">%</span>; }
&lt;/<span style="color: #008000; font-weight: bold">style</span>&gt;
&lt;<span style="color: #008000; font-weight: bold">meta</span> <span style="color: #687822">charset</span><span style="color: #666666">=</span><span style="color: #BA2121">&quot;utf-8&quot;</span>&gt;
&lt;<span style="color: #008000; font-weight: bold">meta</span> <span style="color: #687822">name</span><span style="color: #666666">=</span><span style="color: #BA2121">&quot;viewport&quot;</span> <span style="color: #687822">content</span><span style="color: #666666">=</span><span style="color: #BA2121">&quot;width=device-width,user-scalable=no,initial-scale=1&quot;</span>&gt;
&lt;<span style="color: #008000; font-weight: bold">style</span>&gt;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">body</span><span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">margin</span>:<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>;<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">overflow</span>:<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">hidden</span>;<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">canvas</span><span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"> </span>touch-action:<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">none</span>;<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">width</span>:<span style="color: #bbbbbb"> </span><span style="color: #666666">100</span><span style="color: #B00040">%</span>;<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">height</span>:<span style="color: #bbbbbb"> </span><span style="color: #666666">100</span><span style="color: #B00040">%</span>;<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>&lt;/<span style="color: #008000; font-weight: bold">style</span>&gt;
&lt;/<span style="color: #008000; font-weight: bold">head</span>&gt;
&lt;<span style="color: #008000; font-weight: bold">body</span>&gt;
&lt;<span style="color: #008000; font-weight: bold">canvas</span>&gt;&lt;/<span style="color: #008000; font-weight: bold">canvas</span>&gt;
&lt;<span style="color: #008000; font-weight: bold">script</span> <span style="color: #7D9029">src</span><span style="color: #666666">=</span><span style="color: #BA2121">&quot;//unpkg.com/filament@1.15.0/filament.js&quot;</span>&gt;&lt;/<span style="color: #008000; font-weight: bold">script</span>&gt;
&lt;<span style="color: #008000; font-weight: bold">script</span> <span style="color: #7D9029">src</span><span style="color: #666666">=</span><span style="color: #BA2121">&quot;//unpkg.com/gl-matrix@2.8.1&quot;</span>&gt;&lt;/<span style="color: #008000; font-weight: bold">script</span>&gt;
&lt;<span style="color: #008000; font-weight: bold">script</span> <span style="color: #7D9029">src</span><span style="color: #666666">=</span><span style="color: #BA2121">&quot;triangle.js&quot;</span>&gt;&lt;/<span style="color: #008000; font-weight: bold">script</span>&gt;
&lt;<span style="color: #008000; font-weight: bold">script</span> <span style="color: #687822">src</span><span style="color: #666666">=</span><span style="color: #BA2121">&quot;filament.js&quot;</span>&gt;&lt;/<span style="color: #008000; font-weight: bold">script</span>&gt;
&lt;<span style="color: #008000; font-weight: bold">script</span> <span style="color: #687822">src</span><span style="color: #666666">=</span><span style="color: #BA2121">&quot;//unpkg.com/gl-matrix@2.8.1&quot;</span>&gt;&lt;/<span style="color: #008000; font-weight: bold">script</span>&gt;
&lt;<span style="color: #008000; font-weight: bold">script</span> <span style="color: #687822">src</span><span style="color: #666666">=</span><span style="color: #BA2121">&quot;triangle.js&quot;</span>&gt;&lt;/<span style="color: #008000; font-weight: bold">script</span>&gt;
&lt;/<span style="color: #008000; font-weight: bold">body</span>&gt;
&lt;/<span style="color: #008000; font-weight: bold">html</span>&gt;
</pre></div>
@@ -50,18 +50,18 @@ a mobile-friendly page with a full-screen canvas.</p>
<p>Go ahead and create <code>triangle.js</code> with the following content.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">class</span> App {
<span style="color: #008000; font-weight: bold">constructor</span>() {
<span style="color: #408080; font-style: italic">// TODO: create entities</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: create entities</span>
<span style="color: #008000; font-weight: bold">this</span>.render <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.render.bind(<span style="color: #008000; font-weight: bold">this</span>);
<span style="color: #008000; font-weight: bold">this</span>.resize <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.resize.bind(<span style="color: #008000; font-weight: bold">this</span>);
<span style="color: #008000">window</span>.addEventListener(<span style="color: #BA2121">&#39;resize&#39;</span>, <span style="color: #008000; font-weight: bold">this</span>.resize);
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
}
render() {
<span style="color: #408080; font-style: italic">// TODO: render scene</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: render scene</span>
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
}
resize() {
<span style="color: #408080; font-style: italic">// TODO: adjust viewport and canvas</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: adjust viewport and canvas</span>
}
}
@@ -81,9 +81,9 @@ that define a PBR material. We'll learn more about material packages in the next
<h2>Spawn a local server</h2>
<p>Because of CORS restrictions, your web app cannot fetch the material package directly from the
file system. One way around this is to create a temporary server using Python or node:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>python3 -m http.server <span style="color: #408080; font-style: italic"># Python 3</span>
python -m SimpleHTTPServer <span style="color: #408080; font-style: italic"># Python 2.7</span>
npx http-server -p <span style="color: #666666">8000</span> <span style="color: #408080; font-style: italic"># nodejs</span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>python3 -m http.server <span style="color: #3D7B7B; font-style: italic"># Python 3</span>
python -m SimpleHTTPServer <span style="color: #3D7B7B; font-style: italic"># Python 2.7</span>
npx http-server -p <span style="color: #666666">8000</span> <span style="color: #3D7B7B; font-style: italic"># nodejs</span>
</pre></div>
<p>To see if this works, navigate to <a href="http://localhost:8000">http://localhost:8000</a> and check if you
@@ -185,10 +185,10 @@ view.</p>
<span style="color: #008000; font-weight: bold">this</span>.view.setCamera(<span style="color: #008000; font-weight: bold">this</span>.camera);
<span style="color: #008000; font-weight: bold">this</span>.view.setScene(<span style="color: #008000; font-weight: bold">this</span>.scene);
<span style="color: #408080; font-style: italic">// Set up a blue-green background:</span>
<span style="color: #3D7B7B; font-style: italic">// Set up a blue-green background:</span>
<span style="color: #008000; font-weight: bold">this</span>.renderer.setClearOptions({clearColor<span style="color: #666666">:</span> [<span style="color: #666666">0.0</span>, <span style="color: #666666">0.1</span>, <span style="color: #666666">0.2</span>, <span style="color: #666666">1.0</span>], clear<span style="color: #666666">:</span> <span style="color: #008000; font-weight: bold">true</span>});
<span style="color: #408080; font-style: italic">// Adjust the initial viewport:</span>
<span style="color: #3D7B7B; font-style: italic">// Adjust the initial viewport:</span>
<span style="color: #008000; font-weight: bold">this</span>.resize();
</pre></div>
@@ -198,14 +198,14 @@ However the canvas is still blank!</p>
<p>Recall that our App class has a skeletal render method, which the browser calls every time it needs
to repaint. Often this is 60 times a second.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>render() {
<span style="color: #408080; font-style: italic">// TODO: render scene</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: render scene</span>
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
}
</pre></div>
<p>Let's flesh this out by rotating the triangle and invoking the Filament renderer. Add the following
code to the top of the render method.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #408080; font-style: italic">// Rotate the triangle.</span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic">// Rotate the triangle.</span>
<span style="color: #008000; font-weight: bold">const</span> radians <span style="color: #666666">=</span> <span style="color: #008000">Date</span>.now() <span style="color: #666666">/</span> <span style="color: #666666">1000</span>;
<span style="color: #008000; font-weight: bold">const</span> transform <span style="color: #666666">=</span> mat4.fromRotation(mat4.create(), radians, [<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, <span style="color: #666666">1</span>]);
<span style="color: #008000; font-weight: bold">const</span> tcm <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.getTransformManager();
@@ -213,7 +213,7 @@ code to the top of the render method.</p>
tcm.setTransform(inst, transform);
inst.<span style="color: #AA22FF; font-weight: bold">delete</span>();
<span style="color: #408080; font-style: italic">// Render the frame.</span>
<span style="color: #3D7B7B; font-style: italic">// Render the frame.</span>
<span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain, <span style="color: #008000; font-weight: bold">this</span>.view);
</pre></div>
+23 -22
View File
@@ -77,6 +77,7 @@ set(SRCS
src/RenderTarget.cpp
src/RenderableManager.cpp
src/Renderer.cpp
src/RendererUtils.cpp
src/ResourceAllocator.cpp
src/ResourceList.cpp
src/Scene.cpp
@@ -92,7 +93,6 @@ set(SRCS
src/UniformBuffer.cpp
src/VertexBuffer.cpp
src/View.cpp
src/Viewport.cpp
src/components/CameraManager.cpp
src/components/LightManager.cpp
src/components/RenderableManager.cpp
@@ -118,14 +118,14 @@ set(SRCS
src/details/Texture.cpp
src/details/VertexBuffer.cpp
src/details/View.cpp
src/fg2/Blackboard.cpp
src/fg2/DependencyGraph.cpp
src/fg2/FrameGraph.cpp
src/fg2/FrameGraphPass.cpp
src/fg2/FrameGraphResources.cpp
src/fg2/FrameGraphTexture.cpp
src/fg2/PassNode.cpp
src/fg2/ResourceNode.cpp
src/fg/Blackboard.cpp
src/fg/DependencyGraph.cpp
src/fg/FrameGraph.cpp
src/fg/FrameGraphPass.cpp
src/fg/FrameGraphResources.cpp
src/fg/FrameGraphTexture.cpp
src/fg/PassNode.cpp
src/fg/ResourceNode.cpp
src/fsr.cpp
)
@@ -144,6 +144,7 @@ set(PRIVATE_HDRS
src/PerViewUniforms.h
src/PIDController.h
src/PostProcessManager.h
src/RendererUtils.h
src/RenderPass.h
src/RenderPrimitive.h
src/ResourceAllocator.h
@@ -177,19 +178,19 @@ set(PRIVATE_HDRS
src/details/Texture.h
src/details/VertexBuffer.h
src/details/View.h
src/fg2/Blackboard.h
src/fg2/FrameGraph.h
src/fg2/FrameGraphId.h
src/fg2/FrameGraphPass.h
src/fg2/FrameGraphRenderPass.h
src/fg2/FrameGraphResources.h
src/fg2/FrameGraphTexture.h
src/fg2/Resource.cpp
src/fg2/details/DependencyGraph.h
src/fg2/details/PassNode.h
src/fg2/details/Resource.h
src/fg2/details/ResourceNode.h
src/fg2/details/Utilities.h
src/fg/Blackboard.h
src/fg/FrameGraph.h
src/fg/FrameGraphId.h
src/fg/FrameGraphPass.h
src/fg/FrameGraphRenderPass.h
src/fg/FrameGraphResources.h
src/fg/FrameGraphTexture.h
src/fg/Resource.cpp
src/fg/details/DependencyGraph.h
src/fg/details/PassNode.h
src/fg/details/Resource.h
src/fg/details/ResourceNode.h
src/fg/details/Utilities.h
src/fsr.h
src/materials/fsr/ffx_a.h
src/materials/fsr/ffx_fsr1.h
+3 -5
View File
@@ -42,6 +42,7 @@ set(PRIVATE_HDRS
include/private/backend/CircularBuffer.h
include/private/backend/CommandBufferQueue.h
include/private/backend/CommandStream.h
include/private/backend/Dispatcher.h
include/private/backend/Driver.h
include/private/backend/DriverApi.h
include/private/backend/DriverAPI.inc
@@ -64,8 +65,6 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
src/opengl/gl_headers.h
src/opengl/GLUtils.cpp
src/opengl/GLUtils.h
src/opengl/OpenGLBlitter.cpp
src/opengl/OpenGLBlitter.h
src/opengl/OpenGLContext.cpp
src/opengl/OpenGLContext.h
src/opengl/OpenGLDriver.cpp
@@ -74,8 +73,8 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
src/opengl/OpenGLProgram.cpp
src/opengl/OpenGLProgram.h
src/opengl/OpenGLPlatform.cpp
src/opengl/TimerQuery.cpp
src/opengl/TimerQuery.h
src/opengl/OpenGLTimerQuery.cpp
src/opengl/OpenGLTimerQuery.h
include/private/backend/OpenGLPlatform.h
)
if (EGL)
@@ -88,7 +87,6 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
endif ()
if (ANDROID)
list(APPEND SRCS src/opengl/platforms/ExternalStreamManagerAndroid.cpp)
list(APPEND SRCS src/android/ExternalTextureManagerAndroid.cpp)
list(APPEND SRCS src/opengl/platforms/PlatformEGLAndroid.cpp)
elseif (IOS)
list(APPEND SRCS src/opengl/platforms/PlatformCocoaTouchGL.mm)
+16 -19
View File
@@ -33,7 +33,6 @@
#include <stddef.h>
#include <stdint.h>
namespace filament {
/**
* Types and enums used by filament's driver.
*
@@ -41,24 +40,24 @@ namespace filament {
* internal redeclaration of these types.
* For e.g. Use Texture::Sampler instead of filament::SamplerType.
*/
namespace backend {
namespace filament::backend {
static constexpr uint64_t SWAP_CHAIN_CONFIG_TRANSPARENT = 0x1;
static constexpr uint64_t SWAP_CHAIN_CONFIG_READABLE = 0x2;
static constexpr uint64_t SWAP_CHAIN_CONFIG_ENABLE_XCB = 0x4;
static constexpr uint64_t SWAP_CHAIN_CONFIG_TRANSPARENT = 0x1;
static constexpr uint64_t SWAP_CHAIN_CONFIG_READABLE = 0x2;
static constexpr uint64_t SWAP_CHAIN_CONFIG_ENABLE_XCB = 0x4;
static constexpr uint64_t SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER = 0x8;
static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_VERTEX_SAMPLER_COUNT = 16; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_FRAGMENT_SAMPLER_COUNT = 16; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_SAMPLER_COUNT = 32; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects.
static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_VERTEX_SAMPLER_COUNT = 16; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_FRAGMENT_SAMPLER_COUNT = 16; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_SAMPLER_COUNT = 32; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects.
static_assert(MAX_VERTEX_BUFFER_COUNT <= MAX_VERTEX_ATTRIBUTE_COUNT,
"The number of buffer objects that can be attached to a VertexBuffer must be "
"less than or equal to the maximum number of vertex attributes.");
static constexpr size_t CONFIG_BINDING_COUNT = 8;
static constexpr size_t CONFIG_BINDING_COUNT = 12; // This is guaranteed by OpenGL ES.
/**
* Selects which driver a particular Engine should use.
@@ -142,9 +141,9 @@ struct Viewport {
uint32_t width; //!< width in pixels
uint32_t height; //!< height in pixels
//! get the right coordinate in window space of the viewport
int32_t right() const noexcept { return left + width; }
int32_t right() const noexcept { return left + int32_t(width); }
//! get the top coordinate in window space of the viewport
int32_t top() const noexcept { return bottom + height; }
int32_t top() const noexcept { return bottom + int32_t(height); }
};
/**
@@ -160,7 +159,7 @@ struct DepthRange {
* @see Fence, Fence::wait()
*/
enum class FenceStatus : int8_t {
ERROR = -1, //!< An error occured. The Fence condition is not satisfied.
ERROR = -1, //!< An error occurred. The Fence condition is not satisfied.
CONDITION_SATISFIED = 0, //!< The Fence condition is satisfied.
TIMEOUT_EXPIRED = 1, //!< wait()'s timeout expired. The Fence condition is not satisfied.
};
@@ -169,7 +168,7 @@ enum class FenceStatus : int8_t {
* Status codes for sync objects
*/
enum class SyncStatus : int8_t {
ERROR = -1, //!< An error occured. The Sync is not signaled.
ERROR = -1, //!< An error occurred. The Sync is not signaled.
SIGNALED = 0, //!< The Sync is signaled.
NOT_SIGNALED = 1, //!< The Sync is not signaled yet
};
@@ -789,7 +788,6 @@ enum class BlendFunction : uint8_t {
//! Stream for external textures
enum class StreamType {
NATIVE, //!< Not synchronized but copy-free. Good for video.
TEXTURE_ID, //!< Synchronized, but GL-only and incurs copies. Good for AR on devices before API 26.
ACQUIRED, //!< Synchronized, copy-free, and take a release callback. Good for AR but requires API 26+.
};
@@ -914,7 +912,7 @@ struct ShaderStageFlags {
(fragment && type == ShaderType::FRAGMENT);
}
};
static constexpr ShaderStageFlags ALL_SHADER_STAGE_FLAGS = { .vertex = true, .fragment = true };
static constexpr ShaderStageFlags ALL_SHADER_STAGE_FLAGS = { true, true };
/**
* Selects which buffers to clear at the beginning of the render pass, as well as which buffers
@@ -998,8 +996,7 @@ enum class Workaround : uint16_t {
ALLOW_READ_ONLY_ANCILLARY_FEEDBACK_LOOP
};
} // namespace backend
} // namespace filament
} // namespace filament::backend
template<> struct utils::EnableBitMaskOperators<filament::backend::TargetBufferFlags>
: public std::true_type {};
+1 -1
View File
@@ -80,7 +80,7 @@ public:
* underlying platform is returned and \p backendHint is updated
* accordingly. Can't be nullptr.
*
* @return A pointer to the Plaform object.
* @return A pointer to the Platform object.
*
* @see destroy
*/
@@ -1,5 +1,3 @@
#include <utility>
/*
* Copyright (C) 2018 The Android Open Source Project
*
@@ -20,23 +18,19 @@
#define TNT_FILAMENT_BACKEND_PRIVATE_COMMANDSTREAM_H
#include "private/backend/CircularBuffer.h"
#include "private/backend/Dispatcher.h"
#include "private/backend/Program.h"
#include "private/backend/SamplerGroup.h"
#include "private/backend/Driver.h"
#include <backend/BufferDescriptor.h>
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <backend/PipelineState.h>
#include <backend/PixelBufferDescriptor.h>
#include <backend/PresentCallable.h>
#include <backend/TargetBufferInfo.h>
#include "private/backend/Program.h"
#include "private/backend/SamplerGroup.h"
// FIXME: we'd like to not need this header here.
#include "private/backend/Driver.h"
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/ThreadUtils.h>
@@ -45,40 +39,14 @@
#include <thread>
#include <utility>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
// Set to true to print every commands out on log.d. This requires RTTI and DEBUG
// Set to true to print every command out on log.d. This requires RTTI and DEBUG
#define DEBUG_COMMAND_STREAM false
namespace filament {
namespace backend {
class Driver;
class CommandBase;
/*
* Dispatcher is a data structure containing only function pointers.
* Each function pointer targets code that unpacks the arguments to the driver's method and
* calls it.
*
* Dispatcher's function pointers are populated during initialization and no CommandStream calls
* can be made before that.
*
* When a command is inserted into the stream, the corresponding function pointer is copied
* directly into CommandBase from Dispatcher.
*/
class Dispatcher {
public:
using Execute = void (*)(Driver& driver, CommandBase* self, intptr_t* next);
#define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params)
#define DECL_DRIVER_API(methodName, paramsDecl, params) Execute methodName##_;
#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) Execute methodName##_;
#include "DriverAPI.inc"
};
// ------------------------------------------------------------------------------------------------
namespace filament::backend {
class CommandBase {
static constexpr size_t FILAMENT_OBJECT_ALIGNMENT = alignof(std::max_align_t);
@@ -96,8 +64,10 @@ public:
// executes this command and returns the next one
inline CommandBase* execute(Driver& driver) {
// it is important to return the next command offset by output parameter instead
// of return value -- it allows the compiler to perform the tail call optimization.
// 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
// probably better to pay the cost at just one location.
intptr_t next;
mExecute(driver, this, &next);
return reinterpret_cast<CommandBase*>(reinterpret_cast<intptr_t>(this) + next);
@@ -132,7 +102,7 @@ constexpr decltype(auto) apply(M&& m, D&& d, T&& t) {
/*
* CommandType<> is just a wrapper class to specialize on a pointer-to-member of Driver
* (i.e. a method pointer to a method of Driver of a particular type -- but not the
* method itself). We only do that so we can identify the parameters of that method.
* method itself). We only do that, so we can identify the parameters of that method.
* We won't call through that pointer though.
*/
template<typename... ARGS>
@@ -208,7 +178,7 @@ class NoopCommand : public CommandBase {
}
public:
inline constexpr explicit NoopCommand(void* next) noexcept
: CommandBase(execute), mNext(size_t((char *)next - (char *)this)) { }
: CommandBase(execute), mNext(intptr_t((char *)next - (char *)this)) { }
};
// ------------------------------------------------------------------------------------------------
@@ -216,41 +186,34 @@ public:
#if !defined(NDEBUG) || (FILAMENT_DEBUG_COMMANDS >= FILAMENT_DEBUG_COMMANDS_ENABLE)
// For now, simply pass the method name down as a string and throw away the parameters.
// This is good enough for certain debugging needs and we can improve this later.
#define DEBUG_COMMAND_BEGIN(methodName, sync, ...) mDriver->debugCommandBegin(this, sync, #methodName)
#define DEBUG_COMMAND_END(methodName, sync) mDriver->debugCommandEnd(this, sync, #methodName)
#define DEBUG_COMMAND_BEGIN(methodName, sync, ...) mDriver.debugCommandBegin(this, sync, #methodName)
#define DEBUG_COMMAND_END(methodName, sync) mDriver.debugCommandEnd(this, sync, #methodName)
#else
#define DEBUG_COMMAND_BEGIN(methodName, sync, ...)
#define DEBUG_COMMAND_END(methodName, sync)
#endif
class CommandStream {
// Dispatcher could be a value (instead of pointer), which saves a load when writing commands
// at the expense of a larger CommandStream object (about ~400 bytes)
Dispatcher* mDispatcher = nullptr;
Driver* mDriver = nullptr;
CircularBuffer* UTILS_RESTRICT mCurrentBuffer = nullptr;
#ifndef NDEBUG
// just for debugging...
std::thread::id mThreadId{};
#endif
bool mUsePerformanceCounter = false;
template<typename T>
struct AutoExecute {
T closure;
inline AutoExecute(T&& closure) : closure(std::forward<T>(closure)) {}
inline explicit AutoExecute(T&& closure) : closure(std::forward<T>(closure)) {}
inline ~AutoExecute() { closure(); }
};
public:
CommandStream(Driver& driver, CircularBuffer& buffer) noexcept;
CommandStream(CommandStream const& rhs) noexcept = delete;
CommandStream& operator=(CommandStream const& rhs) noexcept = delete;
public:
#define DECL_DRIVER_API(methodName, paramsDecl, params) \
inline void methodName(paramsDecl) { \
DEBUG_COMMAND_BEGIN(methodName, false, params); \
using Cmd = COMMAND_TYPE(methodName); \
void* const p = allocateCommand(CommandBase::align(sizeof(Cmd))); \
new(p) Cmd(mDispatcher->methodName##_, APPLY(std::move, params)); \
new(p) Cmd(mDispatcher.methodName##_, APPLY(std::move, params)); \
DEBUG_COMMAND_END(methodName, false); \
}
@@ -260,16 +223,16 @@ public:
AutoExecute callOnExit([=](){ \
DEBUG_COMMAND_END(methodName, true); \
}); \
return apply(&Driver::methodName, *mDriver, std::forward_as_tuple(params)); \
return apply(&Driver::methodName, mDriver, std::forward_as_tuple(params)); \
}
#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) \
inline RetType methodName(paramsDecl) { \
DEBUG_COMMAND_BEGIN(methodName, false, params); \
RetType result = mDriver->methodName##S(); \
RetType result = mDriver.methodName##S(); \
using Cmd = COMMAND_TYPE(methodName##R); \
void* const p = allocateCommand(CommandBase::align(sizeof(Cmd))); \
new(p) Cmd(mDispatcher->methodName##_, RetType(result), APPLY(std::move, params)); \
new(p) Cmd(mDispatcher.methodName##_, RetType(result), APPLY(std::move, params)); \
DEBUG_COMMAND_END(methodName, false); \
return result; \
}
@@ -277,10 +240,7 @@ public:
#include "DriverAPI.inc"
public:
CommandStream() noexcept = default;
CommandStream(Driver& driver, CircularBuffer& buffer) noexcept;
// This is for debugging only. Currently CircularBuffer can only be written from a
// 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 {
@@ -315,8 +275,21 @@ public:
private:
inline void* allocateCommand(size_t size) {
assert_invariant(utils::ThreadUtils::isThisThread(mThreadId));
return mCurrentBuffer->allocate(size);
return mCurrentBuffer.allocate(size);
}
// We use a copy of Dispatcher (instead of a pointer) because this removes one dereference
// when executing driver commands.
Driver& UTILS_RESTRICT mDriver;
CircularBuffer& UTILS_RESTRICT mCurrentBuffer;
Dispatcher mDispatcher;
#ifndef NDEBUG
// just for debugging...
std::thread::id mThreadId{};
#endif
bool mUsePerformanceCounter = false;
};
void* CommandStream::allocate(size_t size, size_t alignment) noexcept {
@@ -341,7 +314,6 @@ PodType* CommandStream::allocatePod(size_t count, size_t alignment) noexcept {
return static_cast<PodType*>(allocate(count * sizeof(PodType), alignment));
}
} // namespace backend
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PRIVATE_COMMANDSTREAM_H
@@ -0,0 +1,50 @@
/*
* Copyright (C) 2022 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.
*/
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_DISPATCHER_H
#define TNT_FILAMENT_BACKEND_PRIVATE_DISPATCHER_H
#include <stdint.h>
namespace filament::backend {
class Driver;
class CommandBase;
/*
* Dispatcher is a data structure containing only function pointers.
* Each function pointer targets code that unpacks the arguments to the driver's method and
* calls it.
*
* Dispatcher's function pointers are populated during initialization and no CommandStream calls
* can be made before that.
*
* When a command is inserted into the stream, the corresponding function pointer is copied
* directly into CommandBase from Dispatcher.
*/
class Dispatcher {
public:
using Execute = void (*)(Driver& driver, CommandBase* self, intptr_t* next);
#define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params)
#define DECL_DRIVER_API(methodName, paramsDecl, params) Execute methodName##_;
#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) Execute methodName##_;
#include "DriverAPI.inc"
};
} // namespace filament::backend
#endif //TNT_FILAMENT_BACKEND_PRIVATE_DISPATCHER_H
@@ -17,23 +17,14 @@
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_DRIVER_H
#define TNT_FILAMENT_BACKEND_PRIVATE_DRIVER_H
#include <backend/BufferDescriptor.h>
#include <backend/CallbackHandler.h>
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <backend/PipelineState.h>
#include <backend/PixelBufferDescriptor.h>
#include <backend/PresentCallable.h>
#include <backend/TargetBufferInfo.h>
#include "private/backend/DriverApiForward.h"
#include "private/backend/Program.h"
#include "private/backend/SamplerGroup.h"
#include <utils/compiler.h>
#include <utils/Log.h>
#include <functional>
#include <stdint.h>
@@ -49,8 +40,13 @@
#define FILAMENT_DEBUG_COMMANDS FILAMENT_DEBUG_COMMANDS_NONE
namespace filament {
namespace backend {
namespace filament::backend {
class BufferDescriptor;
class CallbackHandler;
class PixelBufferDescriptor;
class Program;
class SamplerGroup;
template<typename T>
class ConcreteDispatcher;
@@ -59,27 +55,32 @@ class CommandStream;
class Driver {
public:
static size_t getElementTypeSize(ElementType type) noexcept;
virtual ~Driver() noexcept;
static size_t getElementTypeSize(ElementType type) noexcept;
// called from the main thread (NOT the render-thread) at various intervals, this
// is where the driver can execute user callbacks.
virtual void purge() noexcept = 0;
virtual ShaderModel getShaderModel() const noexcept = 0;
virtual Dispatcher& getDispatcher() noexcept = 0;
// Returns the dispatcher. This is only called once during initialization of the CommandStream,
// so it doesn't matter that it's virtual.
virtual Dispatcher getDispatcher() const noexcept = 0;
// called from CommandStream::execute on the render-thread
// the fn function will execute a batch of driver commands
// this gives the driver a chance to wrap their execution in a meaningful manner
// the default implementation simply calls fn
virtual void execute(std::function<void(void)> fn) noexcept;
virtual void execute(std::function<void(void)> const& fn) noexcept;
// This is called on debug build, or when enabled manually on the backend thread side.
virtual void debugCommandBegin(CommandStream* cmds, bool synchronous, const char* methodName) noexcept = 0;
virtual void debugCommandEnd(CommandStream* cmds, bool synchronous, const char* methodName) noexcept = 0;
virtual void debugCommandBegin(CommandStream* cmds,
bool synchronous, const char* methodName) noexcept = 0;
virtual void debugCommandEnd(CommandStream* cmds,
bool synchronous, const char* methodName) noexcept = 0;
/*
* Asynchronous calls here only to provide a type to CommandStream. They must be non-virtual
@@ -101,7 +102,6 @@ public:
#include "private/backend/DriverAPI.inc"
};
} // namespace backend
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PRIVATE_DRIVER_H
@@ -246,11 +246,6 @@ DECL_DRIVER_API_R_N(backend::SwapChainHandle, createSwapChainHeadless,
uint32_t, height,
uint64_t, flags)
DECL_DRIVER_API_R_N(backend::StreamHandle, createStreamFromTextureId,
intptr_t, externalTextureId,
uint32_t, width,
uint32_t, height)
DECL_DRIVER_API_R_0(backend::TimerQueryHandle, createTimerQuery)
@@ -461,14 +456,6 @@ DECL_DRIVER_API_N(readPixels,
uint32_t, height,
backend::PixelBufferDescriptor&&, data)
DECL_DRIVER_API_N(readStreamPixels,
backend::StreamHandle, sh,
uint32_t, x,
uint32_t, y,
uint32_t, width,
uint32_t, height,
backend::PixelBufferDescriptor&&, data)
/*
* Rendering operations
* --------------------
@@ -17,15 +17,12 @@
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_DRIVERAPIFORWARD_H
#define TNT_FILAMENT_BACKEND_PRIVATE_DRIVERAPIFORWARD_H
namespace filament {
namespace backend {
namespace filament::backend {
class CommandStream;
using DriverApi = CommandStream;
} // namespace backend
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PRIVATE_DRIVERAPIFORWARD_H
@@ -61,7 +61,7 @@ public:
*/
template<typename D, typename ... ARGS>
Handle<D> allocateAndConstruct(ARGS&& ... args) noexcept {
Handle<D> h{ allocateHandle(sizeof(D)) };
Handle<D> h{ allocateHandle<sizeof(D)>() };
D* addr = handle_cast<D*>(h);
new(addr) D(std::forward<ARGS>(args)...);
#if HANDLE_TYPE_SAFETY
@@ -84,7 +84,7 @@ public:
*/
template<typename D>
Handle<D> allocate() noexcept {
Handle<D> h{ allocateHandle(sizeof(D)) };
Handle<D> h{ allocateHandle<sizeof(D)>() };
#if HANDLE_TYPE_SAFETY
D* addr = handle_cast<D*>(h);
mLock.lock();
@@ -167,7 +167,7 @@ public:
}
#endif
p->~D();
deallocateHandle(handle.getId(), sizeof(D));
deallocateHandle<sizeof(D)>(handle.getId());
}
}
@@ -249,23 +249,49 @@ private:
utils::LockingPolicy::SpinLock>;
#endif
// this is inlined because we're always called with a constexpr size
HandleBase::HandleId allocateHandle(size_t size) noexcept {
void* p = mHandleArena.alloc(size);
if (UTILS_LIKELY(p)) {
return pointerToHandle(p);
// allocateHandle()/deallocateHandle() selects the pool to use at compile-time based on the
// allocation size this is always inlined, because all these do is to call
// allocateHandleInPool()/deallocateHandleFromPool() with the right pool size.
template<size_t SIZE>
HandleBase::HandleId allocateHandle() noexcept {
if constexpr (SIZE <= P0) { return allocateHandleInPool<P0>(); }
if constexpr (SIZE <= P1) { return allocateHandleInPool<P1>(); }
return allocateHandleInPool<P2>();
}
template<size_t SIZE>
void deallocateHandle(HandleBase::HandleId id) noexcept {
if constexpr (SIZE <= P0) {
deallocateHandleFromPool<P0>(id);
} else if constexpr (SIZE <= P1) {
deallocateHandleFromPool<P1>(id);
} else {
return allocateHandleSlow(size);
deallocateHandleFromPool<P2>(id);
}
}
// this is inlined because we're always called with a constexpr size
void deallocateHandle(HandleBase::HandleId id, size_t size) noexcept {
// allocateHandleInPool()/deallocateHandleFromPool() is NOT inlined, which will cause three
// versions to be generated, one for each pool. Because the arena is synchronized,
// the code generated is not trivial (even if it's not insane either).
template<size_t SIZE>
UTILS_NOINLINE
HandleBase::HandleId allocateHandleInPool() noexcept {
void* p = mHandleArena.alloc(SIZE);
if (UTILS_LIKELY(p)) {
return pointerToHandle(p);
} else {
return allocateHandleSlow(SIZE);
}
}
template<size_t SIZE>
UTILS_NOINLINE
void deallocateHandleFromPool(HandleBase::HandleId id) noexcept {
if (UTILS_LIKELY(isPoolHandle(id))) {
void* p = handleToPointer(id);
mHandleArena.free(p, size);
mHandleArena.free(p, SIZE);
} else {
deallocateHandleSlow(id, size);
deallocateHandleSlow(id, SIZE);
}
}
@@ -82,15 +82,6 @@ public:
virtual void detach(Stream* stream) noexcept = 0;
virtual void updateTexImage(Stream* stream, int64_t* timestamp) noexcept = 0;
// external texture storage
virtual ExternalTexture* createExternalTextureStorage() noexcept = 0;
// this is called synchronously in the application thread (NOT the Driver thread)
virtual void reallocateExternalStorage(ExternalTexture* ets,
uint32_t w, uint32_t h, TextureFormat format) noexcept = 0;
virtual void destroyExternalTextureStorage(ExternalTexture* ets) noexcept = 0;
// The method allows platforms to convert a user-supplied external image object into a new type
// (e.g. HardwareBuffer => EGLImage). It makes sense for the default implementation to do nothing.
virtual AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept { return source; }
+4 -4
View File
@@ -33,8 +33,7 @@
using namespace utils;
namespace filament {
namespace backend {
namespace filament::backend {
CircularBuffer::CircularBuffer(size_t size) {
mData = alloc(size);
@@ -56,6 +55,7 @@ CircularBuffer::~CircularBuffer() noexcept {
// If the system does not support mmap, emulate soft circular buffer with two buffers next
// to each others and a special case in circularize()
UTILS_NOINLINE
void* CircularBuffer::alloc(size_t size) noexcept {
#if HAS_MMAP
void* data = nullptr;
@@ -127,6 +127,7 @@ void* CircularBuffer::alloc(size_t size) noexcept {
#endif
}
UTILS_NOINLINE
void CircularBuffer::dealloc() noexcept {
#if HAS_MMAP
if (mData) {
@@ -162,5 +163,4 @@ void CircularBuffer::circularize() noexcept {
mTail = mHead;
}
} // namespace backend
} // namespace filament
} // namespace filament::backend
+7 -9
View File
@@ -29,8 +29,7 @@
using namespace utils;
namespace filament {
namespace backend {
namespace filament::backend {
// ------------------------------------------------------------------------------------------------
// A few utility functions for debugging...
@@ -57,9 +56,9 @@ static UTILS_NOINLINE UTILS_UNUSED std::string extractMethodName(std::string& co
// ------------------------------------------------------------------------------------------------
CommandStream::CommandStream(Driver& driver, CircularBuffer& buffer) noexcept
: mDispatcher(&driver.getDispatcher()),
mDriver(&driver),
mCurrentBuffer(&buffer)
: mDriver(driver),
mCurrentBuffer(buffer),
mDispatcher(driver.getDispatcher())
#ifndef NDEBUG
, mThreadId(ThreadUtils::getThreadId())
#endif
@@ -84,8 +83,8 @@ void CommandStream::execute(void* buffer) {
}
}
mDriver->execute([this, buffer]() {
Driver& UTILS_RESTRICT driver = *mDriver;
mDriver.execute([this, buffer]() {
Driver& UTILS_RESTRICT driver = mDriver;
CommandBase* UTILS_RESTRICT base = static_cast<CommandBase*>(buffer);
while (UTILS_LIKELY(base)) {
base = base->execute(driver);
@@ -152,5 +151,4 @@ void CustomCommand::execute(Driver&, CommandBase* base, intptr_t* next) noexcept
static_cast<CustomCommand*>(base)->~CustomCommand();
}
} // namespace backend
} // namespace filament
} // namespace filament::backend
+16 -10
View File
@@ -23,9 +23,9 @@
#include <utils/compiler.h>
#include <utils/Systrace.h>
#include <cstddef>
#include <utility>
#include <stddef.h>
#include <stdint.h>
#define DEBUG_LEVEL_NONE 0
@@ -46,10 +46,10 @@
namespace filament::backend {
template<typename ConcreteDriver>
class ConcreteDispatcher final : public Dispatcher {
class ConcreteDispatcher {
public:
// initialize the dispatch table
ConcreteDispatcher() noexcept;
static Dispatcher make() noexcept;
private:
#define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params)
@@ -72,13 +72,19 @@ private:
template<typename ConcreteDriver>
UTILS_NOINLINE
ConcreteDispatcher<ConcreteDriver>::ConcreteDispatcher() noexcept : Dispatcher() {
#define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params)
#define DECL_DRIVER_API(methodName, paramsDecl, params) methodName##_ = &ConcreteDispatcher::methodName;
#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) methodName##_ = &ConcreteDispatcher::methodName;
#include "private/backend/DriverAPI.inc"
}
Dispatcher ConcreteDispatcher<ConcreteDriver>::make() noexcept {
Dispatcher dispatcher;
#define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params)
#define DECL_DRIVER_API(methodName, paramsDecl, params) \
dispatcher.methodName##_ = &ConcreteDispatcher::methodName;
#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) \
dispatcher.methodName##_ = &ConcreteDispatcher::methodName;
#include "private/backend/DriverAPI.inc"
return dispatcher;
}
} // namespace filament::backend
+14 -19
View File
@@ -15,6 +15,8 @@
*/
#include "private/backend/Driver.h"
#include "private/backend/AcquiredImage.h"
#include "private/backend/CommandStream.h"
#include "DriverBase.h"
@@ -25,20 +27,15 @@
#include <math/vec4.h>
#include <backend/BufferDescriptor.h>
#include <backend/PixelBufferDescriptor.h>
#include <utils/Systrace.h>
using namespace utils;
using namespace filament::math;
namespace filament {
namespace filament::backend {
using namespace math;
namespace backend {
DriverBase::DriverBase(Dispatcher* dispatcher) noexcept
: mDispatcher(dispatcher) {
DriverBase::DriverBase() noexcept {
if constexpr (UTILS_HAS_THREADING) {
// This thread services user callbacks
mServiceThread = std::thread([this]() {
@@ -75,7 +72,6 @@ DriverBase::~DriverBase() noexcept {
lock.unlock();
mServiceThread.join();
}
delete mDispatcher;
}
// ------------------------------------------------------------------------------------------------
@@ -169,14 +165,6 @@ void DriverBase::debugCommandEnd(CommandStream* cmds, bool synchronous, const ch
}
}
// ------------------------------------------------------------------------------------------------
Driver::~Driver() noexcept = default;
void Driver::execute(std::function<void(void)> fn) noexcept {
fn();
}
size_t Driver::getElementTypeSize(ElementType type) noexcept {
switch (type) {
case ElementType::BYTE: return sizeof(int8_t);
@@ -208,5 +196,12 @@ size_t Driver::getElementTypeSize(ElementType type) noexcept {
}
}
} // namespace backend
} // namespace filament
// ------------------------------------------------------------------------------------------------
Driver::~Driver() noexcept = default;
void Driver::execute(std::function<void(void)> const& fn) noexcept {
fn();
}
} // namespace filament::backend
+5 -10
View File
@@ -22,14 +22,14 @@
#include <backend/Platform.h>
#include <backend/BufferDescriptor.h>
#include <backend/DriverEnums.h>
#include <backend/CallbackHandler.h>
#include "private/backend/AcquiredImage.h"
#include "private/backend/Dispatcher.h"
#include "private/backend/Driver.h"
#include "private/backend/SamplerGroup.h"
#include <array>
#include <condition_variable>
#include <memory>
#include <mutex>
@@ -41,7 +41,7 @@
namespace filament::backend {
class Dispatcher;
struct AcquiredImage;
/*
* Hardware handles
@@ -72,7 +72,7 @@ struct HwBufferObject : public HwBase {
uint32_t byteCount{};
HwBufferObject() noexcept = default;
HwBufferObject(uint32_t byteCount) noexcept : byteCount(byteCount) {}
explicit HwBufferObject(uint32_t byteCount) noexcept : byteCount(byteCount) {}
};
struct HwIndexBuffer : public HwBase {
@@ -167,21 +167,16 @@ struct HwTimerQuery : public HwBase {
class DriverBase : public Driver {
public:
DriverBase() = delete;
explicit DriverBase(Dispatcher* dispatcher) noexcept;
DriverBase() noexcept;
~DriverBase() noexcept override;
void purge() noexcept final;
Dispatcher& getDispatcher() noexcept final { return *mDispatcher; }
// --------------------------------------------------------------------------------------------
// Privates
// --------------------------------------------------------------------------------------------
protected:
Dispatcher* mDispatcher;
class CallbackDataDetails;
// Helpers...
+1 -1
View File
@@ -28,7 +28,7 @@ namespace filament::backend {
#ifndef NDEBUG
static char const * const kOurNamespace = "filament::";
static char const * const kOurNamespace = "filament::backend";
// removes all occurrences of "what" from "str"
UTILS_NOINLINE
@@ -1,223 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ExternalTextureManagerAndroid.h"
#include <utils/api_level.h>
#include <utils/compiler.h>
#include <utils/Log.h>
#include <dlfcn.h>
using namespace utils;
namespace filament {
using namespace backend;
template <typename T>
static void loadSymbol(T*& pfn, const char *symbol) noexcept {
pfn = (T*)dlsym(RTLD_DEFAULT, symbol);
}
// ------------------------------------------------------------------------------------------------
namespace ndk {
/*
* This mimics the GraphicBuffer class for pre-API 26
*/
template<typename NATIVE_TYPE, typename REF>
struct ANativeObjectBase : public NATIVE_TYPE, public REF {
};
struct android_native_base_t {
unsigned int magic;
unsigned int version;
void* reserved[4];
void (* incRef)(struct android_native_base_t* base);
void (* decRef)(struct android_native_base_t* base);
};
struct ANativeWindowBuffer {
struct android_native_base_t common;
unsigned int width;
unsigned int height;
unsigned int stride;
unsigned int format;
unsigned int usage_deprecated;
uintptr_t layerCount;
void* reserved[1];
const void* handle;
uint64_t usage;
void* reserved_proc[8 - (sizeof(uint64_t) / sizeof(void*))];
};
struct RefBase {
virtual ~RefBase() = default;
void* ref;
};
struct GraphicBuffer : public ANativeObjectBase<ANativeWindowBuffer, RefBase> {
};
struct GraphicBufferWrapper {
GraphicBuffer* graphicBuffer;
};
} // namespace ndk
// ------------------------------------------------------------------------------------------------
using namespace ndk;
struct EGLExternalTexture : public ExternalTextureManagerAndroid::ExternalTexture {
GraphicBufferWrapper* graphicBufferWrapper = nullptr;
};
ExternalTextureManagerAndroid& ExternalTextureManagerAndroid::create() noexcept {
return *(new ExternalTextureManagerAndroid{});
}
void ExternalTextureManagerAndroid::destroy(ExternalTextureManagerAndroid* pExternalTextureManager) noexcept {
delete pExternalTextureManager;
}
// called on gl thread
ExternalTextureManagerAndroid::ExternalTextureManagerAndroid() noexcept
: mVm(VirtualMachineEnv::get()) {
}
// not quite sure on which thread this is going to be called
ExternalTextureManagerAndroid::~ExternalTextureManagerAndroid() noexcept {
if (__builtin_available(android 26, *)) {
} else {
if (mGraphicBufferClass) {
JNIEnv* env = VirtualMachineEnv::getThreadEnvironment();
if (env) {
env->DeleteGlobalRef(mGraphicBufferClass);
}
}
}
}
// called on gl thread
backend::Platform::ExternalTexture* ExternalTextureManagerAndroid::createExternalTexture() noexcept {
if (__builtin_available(android 26, *)) {
} else {
// initialize java stuff on-demand
if (!mGraphicBufferClass) {
JNIEnv* env = mVm.getEnvironment();
mGraphicBufferClass = env->FindClass("android/view/GraphicBuffer");
mGraphicBuffer_nCreateGraphicBuffer = env->GetStaticMethodID(
mGraphicBufferClass, "nCreateGraphicBuffer", "(IIII)J");
mGraphicBuffer_nDestroyGraphicBuffer = env->GetStaticMethodID(
mGraphicBufferClass, "nDestroyGraphicBuffer", "(J)V");
mGraphicBufferClass = static_cast<jclass>(env->NewGlobalRef(mGraphicBufferClass));
}
}
EGLExternalTexture* ets = new EGLExternalTexture;
return ets;
}
// called on app thread
void ExternalTextureManagerAndroid::reallocate(
backend::Platform::ExternalTexture* ets, uint32_t w, uint32_t h,
backend::TextureFormat format, uint64_t usage) noexcept {
destroyStorage(ets);
alloc(ets, w, h, format, usage);
}
// called on gl thread
void ExternalTextureManagerAndroid::destroy(backend::Platform::ExternalTexture* ets) noexcept {
destroyStorage(ets);
delete static_cast<EGLExternalTexture*>(ets);
}
// called on app thread
void ExternalTextureManagerAndroid::alloc(
backend::Platform::ExternalTexture* t,
uint32_t w, uint32_t h, TextureFormat format, uint64_t usage) noexcept {
EGLExternalTexture* ets = static_cast<EGLExternalTexture*>(t);
AHardwareBuffer_Desc desc = { w, h, 1, 0, usage, 0, 0, 0 };
switch (format) {
case TextureFormat::RGB8:
// don't use R8G8B8 here because some drivers produce garbled images
desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
break;
case TextureFormat::RGBA8:
desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
break;
case TextureFormat::RGB565:
desc.format = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
break;
case TextureFormat::RGB10_A2:
desc.format = AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
break;
default:
slog.e << "Unsupported format " << (int)format << ", use RGBA8 or RGB8 only."
<< io::endl;
return;
}
if (__builtin_available(android 26, *)) {
// allocate new storage...
AHardwareBuffer* buffer = nullptr;
if (AHardwareBuffer_allocate(&desc, &buffer) < 0) {
slog.e << "AHardwareBuffer_allocate() failed" << io::endl;
return;
}
ets->hardwareBuffer = buffer;
} else {
// note: This is called on the application thread (not the GL thread)
JNIEnv* env = VirtualMachineEnv::getThreadEnvironment();
if (!env) {
return; // this should not happen
}
jlong graphicBufferWrapperJni = env->CallStaticLongMethod(mGraphicBufferClass,
mGraphicBuffer_nCreateGraphicBuffer, w, h, desc.format, usage);
VirtualMachineEnv::handleException(env);
if (graphicBufferWrapperJni) {
GraphicBuffer* const gb = ((GraphicBufferWrapper*)graphicBufferWrapperJni)->graphicBuffer;
ets->graphicBufferWrapper = (GraphicBufferWrapper*)graphicBufferWrapperJni;
ets->clientBuffer = static_cast<ANativeWindowBuffer*>(gb);
}
}
}
// called on gl thread
void ExternalTextureManagerAndroid::destroyStorage(backend::Platform::ExternalTexture* t) noexcept {
EGLExternalTexture* ets = static_cast<EGLExternalTexture*>(t);
if (__builtin_available(android 26, *)) {
// destroy the current storage if any
if (ets->hardwareBuffer) {
AHardwareBuffer_release(ets->hardwareBuffer);
ets->hardwareBuffer = nullptr;
}
} else {
if (ets->graphicBufferWrapper) {
JNIEnv* env = VirtualMachineEnv::get().getEnvironment();
env->CallStaticVoidMethod(mGraphicBufferClass,
mGraphicBuffer_nDestroyGraphicBuffer, (jlong)ets->graphicBufferWrapper);
VirtualMachineEnv::handleException(env);
ets->graphicBufferWrapper = nullptr;
}
}
}
} // namespace filament
@@ -1,86 +0,0 @@
/*
* Copyright (C) 2018 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.
*/
#ifndef TNT_FILAMENT_DRIVER_ANDROID_EXTERNAL_TEXTURE_MANAGER_ANDROID_H
#define TNT_FILAMENT_DRIVER_ANDROID_EXTERNAL_TEXTURE_MANAGER_ANDROID_H
#include "private/backend/VirtualMachineEnv.h"
#include <backend/DriverEnums.h>
#include <backend/Platform.h>
#include <android/api-level.h>
#include <android/hardware_buffer.h>
namespace filament {
/*
* ExternalTextureManagerAndroid::ExternalTexture is basically a wrapper for AHardwareBuffer.
*
* This class doesn't rely on GL or EGL, and could be used for other Android platform if needed
* (e.g. Vulkan).
*
* ExternalTextureManagerAndroid handle allocation/destruction using either Java or the NDK,
* whichever is available.
*/
class ExternalTextureManagerAndroid {
public:
struct ExternalTexture : public backend::Platform::ExternalTexture {
void* clientBuffer = nullptr;
AHardwareBuffer* hardwareBuffer = nullptr;
};
// must be called on backend thread
static ExternalTextureManagerAndroid& create() noexcept;
// must be called on backend thread
static void destroy(ExternalTextureManagerAndroid* pExternalTextureManager) noexcept;
// must be called on backend thread (only because we don't synchronize
backend::Platform::ExternalTexture* createExternalTexture() noexcept;
// called on app thread
void reallocate(
backend::Platform::ExternalTexture* ets, uint32_t w, uint32_t h,
backend::TextureFormat format, uint64_t usage) noexcept;
// must be called on backend thread
void destroy(backend::Platform::ExternalTexture* ets) noexcept;
private:
ExternalTextureManagerAndroid() noexcept;
~ExternalTextureManagerAndroid() noexcept;
// called on app thread
void alloc(backend::Platform::ExternalTexture* ets,
uint32_t w, uint32_t h, backend::TextureFormat format, uint64_t usage) noexcept;
// called on gl thread
void destroyStorage(backend::Platform::ExternalTexture* ets) noexcept;
VirtualMachineEnv& mVm;
jclass mGraphicBufferClass = nullptr;
jmethodID mGraphicBuffer_nCreateGraphicBuffer = nullptr;
jmethodID mGraphicBuffer_nDestroyGraphicBuffer = nullptr;
};
} // namespace filament
#endif // TNT_FILAMENT_DRIVER_ANDROID_EXTERNAL_TEXTURE_MANAGER_ANDROID_H
@@ -26,7 +26,6 @@
namespace filament {
namespace backend {
namespace metal {
struct MetalContext;
@@ -133,7 +132,6 @@ private:
};
} // namespace metal
} // namespace backend
} // namespace filament
+1 -3
View File
@@ -23,7 +23,6 @@
namespace filament {
namespace backend {
namespace metal {
static const char* functionLibrary = R"(
#include <metal_stdlib>
@@ -300,7 +299,7 @@ void MetalBlitter::blitDepthPlane(id<MTLCommandBuffer> cmdBuffer, bool blitColor
}
id<MTLFunction> fragmentFunction = getBlitFragmentFunction(key);
PipelineState pipelineState {
MetalPipelineState pipelineState {
.vertexFunction = getBlitVertexFunction(),
.fragmentFunction = fragmentFunction,
.vertexDescription = {},
@@ -530,6 +529,5 @@ id<MTLFunction> MetalBlitter::getBlitFragmentFunction(BlitFunctionKey key) {
return function;
}
} // namespace metal
} // namespace backend
} // namespace filament
-2
View File
@@ -26,7 +26,6 @@
namespace filament {
namespace backend {
namespace metal {
class MetalBuffer {
public:
@@ -94,7 +93,6 @@ private:
void copyIntoStreamBuffer(void* src, size_t size);
};
} // namespace metal
} // namespace backend
} // namespace filament
@@ -22,7 +22,6 @@
namespace filament {
namespace backend {
namespace metal {
MetalBuffer::MetalBuffer(MetalContext& context, BufferUsage usage, size_t size, bool forceGpuBuffer)
: mBufferSize(size), mContext(context) {
@@ -206,6 +205,5 @@ void MetalBuffer::bindBuffers(id<MTLCommandBuffer> cmdBuffer, id<MTLRenderComman
}
}
} // namespace metal
} // namespace backend
} // namespace filament
@@ -25,7 +25,6 @@
namespace filament {
namespace backend {
namespace metal {
struct MetalContext;
@@ -78,7 +77,6 @@ private:
static constexpr uint32_t TIME_BEFORE_EVICTION = 10;
};
} // namespace metal
} // namespace backend
} // namespace filament
@@ -26,7 +26,6 @@
namespace filament {
namespace backend {
namespace metal {
MetalBufferPoolEntry const* MetalBufferPool::acquireBuffer(size_t numBytes) {
std::lock_guard<std::mutex> lock(mMutex);
@@ -110,6 +109,5 @@ void MetalBufferPool::reset() noexcept {
mFreeStages.clear();
}
} // namespace metal
} // namespace backend
} // namespace filament
+2 -4
View File
@@ -36,14 +36,13 @@
namespace filament {
namespace backend {
namespace metal {
class MetalDriver;
class MetalBlitter;
class MetalBufferPool;
class MetalRenderTarget;
class MetalSwapChain;
class TimerQueryInterface;
class MetalTimerQueryInterface;
struct MetalUniformBuffer;
struct MetalIndexBuffer;
struct MetalSamplerGroup;
@@ -113,7 +112,7 @@ struct MetalContext {
MTLSharedEventListener* eventListener = nil;
uint64_t signalId = 1;
TimerQueryInterface* timerQueryImpl;
MetalTimerQueryInterface* timerQueryImpl;
std::stack<const char*> groupMarkers;
@@ -134,7 +133,6 @@ id<MTLTexture> getOrCreateEmptyTexture(MetalContext* context);
bool isInRenderPass(MetalContext* context);
} // namespace metal
} // namespace backend
} // namespace filament
@@ -25,7 +25,6 @@
namespace filament {
namespace backend {
namespace metal {
void initializeSupportedGpuFamilies(MetalContext* context) {
auto& highestSupportedFamily = context->highestSupportedGpuFamily;
@@ -145,6 +144,5 @@ bool isInRenderPass(MetalContext* context) {
return context->currentRenderPassEncoder != nil;
}
} // namespace metal
} // namespace backend
} // namespace filament
+7 -9
View File
@@ -31,8 +31,6 @@ namespace backend {
class MetalPlatform;
namespace metal {
class MetalBuffer;
struct MetalUniformBuffer;
struct MetalContext;
@@ -44,31 +42,32 @@ struct UniformBufferState;
#endif
class MetalDriver final : public DriverBase {
explicit MetalDriver(backend::MetalPlatform* platform) noexcept;
explicit MetalDriver(MetalPlatform* platform) noexcept;
~MetalDriver() noexcept override;
Dispatcher getDispatcher() const noexcept final;
public:
static Driver* create(backend::MetalPlatform* platform);
static Driver* create(MetalPlatform* platform);
private:
friend class MetalSwapChain;
backend::MetalPlatform& mPlatform;
MetalPlatform& mPlatform;
MetalContext* mContext;
ShaderModel getShaderModel() const noexcept final;
// Overrides the default implementation by wrapping the call to fn in an @autoreleasepool block.
void execute(std::function<void(void)> fn) noexcept final;
void execute(std::function<void(void)> const& fn) noexcept final;
/*
* Driver interface
*/
template<typename T>
friend class backend::ConcreteDispatcher;
friend class ConcreteDispatcher;
#define DECL_DRIVER_API(methodName, paramsDecl, params) \
UTILS_ALWAYS_INLINE inline void methodName(paramsDecl);
@@ -86,7 +85,7 @@ private:
* Memory management
*/
backend::HandleAllocatorMTL mHandleAllocator;
HandleAllocatorMTL mHandleAllocator;
template<typename D>
Handle<D> alloc_handle() {
@@ -126,7 +125,6 @@ private:
};
} // namespace metal
} // namespace backend
} // namespace filament
+30 -44
View File
@@ -41,22 +41,23 @@ namespace filament {
namespace backend {
Driver* MetalDriverFactory::create(MetalPlatform* const platform) {
return metal::MetalDriver::create(platform);
return MetalDriver::create(platform);
}
namespace metal {
UTILS_NOINLINE
Driver* MetalDriver::create(MetalPlatform* const platform) {
assert_invariant(platform);
return new MetalDriver(platform);
}
MetalDriver::MetalDriver(backend::MetalPlatform* platform) noexcept
: DriverBase(new ConcreteDispatcher<MetalDriver>()),
mPlatform(*platform),
mContext(new MetalContext),
mHandleAllocator("Handles", FILAMENT_METAL_HANDLE_ARENA_SIZE_IN_MB * 1024U * 1024U) {
Dispatcher MetalDriver::getDispatcher() const noexcept {
return ConcreteDispatcher<MetalDriver>::make();
}
MetalDriver::MetalDriver(MetalPlatform* platform) noexcept
: mPlatform(*platform),
mContext(new MetalContext),
mHandleAllocator("Handles", FILAMENT_METAL_HANDLE_ARENA_SIZE_IN_MB * 1024U * 1024U) {
mContext->driver = this;
mContext->device = mPlatform.createDevice();
@@ -108,7 +109,7 @@ MetalDriver::MetalDriver(backend::MetalPlatform* platform) noexcept
mContext->blitter = new MetalBlitter(*mContext);
if (@available(iOS 12, *)) {
mContext->timerQueryImpl = new TimerQueryFence(*mContext);
mContext->timerQueryImpl = new MetalTimerQueryFence(*mContext);
} else {
mContext->timerQueryImpl = new TimerQueryNoop();
}
@@ -149,18 +150,18 @@ void MetalDriver::beginFrame(int64_t monotonic_clock_ns, uint32_t frameId) {
}
void MetalDriver::setFrameScheduledCallback(Handle<HwSwapChain> sch,
backend::FrameScheduledCallback callback, void* user) {
FrameScheduledCallback callback, void* user) {
auto* swapChain = handle_cast<MetalSwapChain>(sch);
swapChain->setFrameScheduledCallback(callback, user);
}
void MetalDriver::setFrameCompletedCallback(Handle<HwSwapChain> sch,
backend::FrameCompletedCallback callback, void* user) {
FrameCompletedCallback callback, void* user) {
auto* swapChain = handle_cast<MetalSwapChain>(sch);
swapChain->setFrameCompletedCallback(callback, user);
}
void MetalDriver::execute(std::function<void(void)> fn) noexcept {
void MetalDriver::execute(std::function<void(void)> const& fn) noexcept {
@autoreleasepool {
fn();
}
@@ -291,7 +292,7 @@ void MetalDriver::createDefaultRenderTargetR(Handle<HwRenderTarget> rth, int dum
void MetalDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
TargetBufferFlags targetBufferFlags, uint32_t width, uint32_t height,
uint8_t samples, backend::MRT color,
uint8_t samples, MRT color,
TargetBufferInfo depth, TargetBufferInfo stencil) {
// Clamp sample count to what the device supports.
auto& sc = mContext->sampleCountLookup;
@@ -344,7 +345,7 @@ void MetalDriver::createSyncR(Handle<HwSync> sh, int) {
}
void MetalDriver::createSwapChainR(Handle<HwSwapChain> sch, void* nativeWindow, uint64_t flags) {
if (UTILS_UNLIKELY(flags & backend::SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER)) {
if (UTILS_UNLIKELY(flags & SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER)) {
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef) nativeWindow;
construct_handle<MetalSwapChain>(sch, *mContext, pixelBuffer, flags);
} else {
@@ -358,10 +359,6 @@ void MetalDriver::createSwapChainHeadlessR(Handle<HwSwapChain> sch,
construct_handle<MetalSwapChain>(sch, *mContext, width, height, flags);
}
void MetalDriver::createStreamFromTextureIdR(Handle<HwStream>, intptr_t externalTextureId,
uint32_t width, uint32_t height) {
}
void MetalDriver::createTimerQueryR(Handle<HwTimerQuery> tqh, int) {
// nothing to do, timer query was constructed in createTimerQueryS
}
@@ -430,10 +427,6 @@ Handle<HwSwapChain> MetalDriver::createSwapChainHeadlessS() noexcept {
return alloc_handle<MetalSwapChain>();
}
Handle<HwStream> MetalDriver::createStreamFromTextureIdS() noexcept {
return {};
}
Handle<HwTimerQuery> MetalDriver::createTimerQueryS() noexcept {
// The handle must be constructed here, as a synchronous call to getTimerQueryValue might happen
// before createTimerQueryR is executed.
@@ -569,7 +562,7 @@ Handle<HwStream> MetalDriver::createStreamAcquired() {
}
void MetalDriver::setAcquiredImage(Handle<HwStream> sh, void* image,
backend::CallbackHandler* handler, backend::StreamCallback cb, void* userData) {
CallbackHandler* handler, StreamCallback cb, void* userData) {
}
void MetalDriver::setStreamDimensions(Handle<HwStream> stream, uint32_t width,
@@ -581,7 +574,7 @@ int64_t MetalDriver::getStreamTimestamp(Handle<HwStream> stream) {
return 0;
}
void MetalDriver::updateStreams(backend::DriverApi* driver) {
void MetalDriver::updateStreams(DriverApi* driver) {
}
@@ -1052,14 +1045,9 @@ void MetalDriver::readPixels(Handle<HwRenderTarget> src, uint32_t x, uint32_t y,
}];
}
void MetalDriver::readStreamPixels(Handle<HwStream> sh, uint32_t x, uint32_t y, uint32_t width,
uint32_t height, PixelBufferDescriptor&& data) {
}
void MetalDriver::blit(TargetBufferFlags buffers,
Handle<HwRenderTarget> dst, backend::Viewport dstRect,
Handle<HwRenderTarget> src, backend::Viewport srcRect,
Handle<HwRenderTarget> dst, Viewport dstRect,
Handle<HwRenderTarget> src, Viewport srcRect,
SamplerMagFilter filter) {
// If we're the in middle of a render pass, finish it.
// This condition should only occur during copyFrame. It's okay to end the render pass because
@@ -1166,7 +1154,7 @@ void MetalDriver::blit(TargetBufferFlags buffers,
mContext->blitter->blit(getPendingCommandBuffer(mContext), args);
}
void MetalDriver::draw(backend::PipelineState ps, Handle<HwRenderPrimitive> rph, uint32_t instanceCount) {
void MetalDriver::draw(PipelineState ps, Handle<HwRenderPrimitive> rph, uint32_t instanceCount) {
ASSERT_PRECONDITION(mContext->currentRenderPassEncoder != nullptr,
"Attempted to draw without a valid command encoder.");
auto primitive = handle_cast<MetalRenderPrimitive>(rph);
@@ -1196,7 +1184,7 @@ void MetalDriver::draw(backend::PipelineState ps, Handle<HwRenderPrimitive> rph,
if (depthAttachment) {
depthPixelFormat = depthAttachment.getPixelFormat();
}
metal::PipelineState pipelineState {
MetalPipelineState pipelineState {
.vertexFunction = program->vertexFunction,
.fragmentFunction = program->fragmentFunction,
.vertexDescription = primitive->vertexDescription,
@@ -1304,15 +1292,15 @@ void MetalDriver::draw(backend::PipelineState ps, Handle<HwRenderPrimitive> rph,
return mContext->samplerStateCache.getOrCreateState(s);
};
id<MTLTexture> texturesToBindVertex[backend::MAX_VERTEX_SAMPLER_COUNT] = {};
id<MTLSamplerState> samplersToBindVertex[backend::MAX_VERTEX_SAMPLER_COUNT] = {};
id<MTLTexture> texturesToBindVertex[MAX_VERTEX_SAMPLER_COUNT] = {};
id<MTLSamplerState> samplersToBindVertex[MAX_VERTEX_SAMPLER_COUNT] = {};
enumerateSamplerGroups(program, ShaderType::VERTEX,
[this, &getTextureToBind, &getSamplerToBind, &texturesToBindVertex, &samplersToBindVertex](
const SamplerGroup::Sampler* sampler, uint8_t binding) {
// We currently only support a max of MAX_VERTEX_SAMPLER_COUNT samplers. Ignore any additional
// samplers that may be bound.
if (binding >= backend::MAX_VERTEX_SAMPLER_COUNT) {
if (binding >= MAX_VERTEX_SAMPLER_COUNT) {
return;
}
@@ -1336,21 +1324,21 @@ void MetalDriver::draw(backend::PipelineState ps, Handle<HwRenderPrimitive> rph,
}
}
NSRange vertexSamplerRange = NSMakeRange(0, backend::MAX_VERTEX_SAMPLER_COUNT);
NSRange vertexSamplerRange = NSMakeRange(0, MAX_VERTEX_SAMPLER_COUNT);
[mContext->currentRenderPassEncoder setVertexTextures:texturesToBindVertex
withRange:vertexSamplerRange];
[mContext->currentRenderPassEncoder setVertexSamplerStates:samplersToBindVertex
withRange:vertexSamplerRange];
id<MTLTexture> texturesToBindFragment[backend::MAX_FRAGMENT_SAMPLER_COUNT] = {};
id<MTLSamplerState> samplersToBindFragment[backend::MAX_FRAGMENT_SAMPLER_COUNT] = {};
id<MTLTexture> texturesToBindFragment[MAX_FRAGMENT_SAMPLER_COUNT] = {};
id<MTLSamplerState> samplersToBindFragment[MAX_FRAGMENT_SAMPLER_COUNT] = {};
enumerateSamplerGroups(program, ShaderType::FRAGMENT,
[this, &getTextureToBind, &getSamplerToBind, &texturesToBindFragment, &samplersToBindFragment](
const SamplerGroup::Sampler* sampler, uint8_t binding) {
// We currently only support a max of MAX_FRAGMENT_SAMPLER_COUNT samplers. Ignore any additional
// samplers that may be bound.
if (binding >= backend::MAX_FRAGMENT_SAMPLER_COUNT) {
if (binding >= MAX_FRAGMENT_SAMPLER_COUNT) {
return;
}
@@ -1374,7 +1362,7 @@ void MetalDriver::draw(backend::PipelineState ps, Handle<HwRenderPrimitive> rph,
}
}
NSRange fragmentSamplerRange = NSMakeRange(0, backend::MAX_FRAGMENT_SAMPLER_COUNT);
NSRange fragmentSamplerRange = NSMakeRange(0, MAX_FRAGMENT_SAMPLER_COUNT);
[mContext->currentRenderPassEncoder setFragmentTextures:texturesToBindFragment
withRange:fragmentSamplerRange];
[mContext->currentRenderPassEncoder setFragmentSamplerStates:samplersToBindFragment
@@ -1479,10 +1467,8 @@ void MetalDriver::enumerateBoundUniformBuffers(
}
}
} // namespace metal
// explicit instantiation of the Dispatcher
template class ConcreteDispatcher<metal::MetalDriver>;
template class ConcreteDispatcher<MetalDriver>;
} // namespace backend
} // namespace filament
@@ -24,7 +24,7 @@ class Driver;
class MetalDriverFactory {
public:
static Driver* create(backend::MetalPlatform* platform);
static Driver* create(MetalPlatform* platform);
};
} // namespace backend
-2
View File
@@ -27,7 +27,6 @@
namespace filament {
namespace backend {
namespace metal {
struct MetalContext;
@@ -405,7 +404,6 @@ inline MTLTextureSwizzleChannels getSwizzleChannels(TextureSwizzle r, TextureSwi
getSwizzle(a));
}
} // namespace metal
} // namespace backend
} // namespace filament
-2
View File
@@ -20,7 +20,6 @@
namespace filament {
namespace backend {
namespace metal {
MTLPixelFormat getMetalFormat(MetalContext* context, TextureFormat format) noexcept {
switch (format) {
@@ -207,6 +206,5 @@ MTLPixelFormat getMetalFormat(MetalContext* context, TextureFormat format) noexc
return MTLPixelFormatInvalid;
}
} // namespace metal
} // namespace backend
} // namespace filament
@@ -24,7 +24,6 @@
namespace filament {
namespace backend {
namespace metal {
struct MetalContext;
@@ -129,7 +128,6 @@ private:
} mSwizzle;
};
} // namespace metal
} // namespace backend
} // namespace filament
@@ -32,7 +32,6 @@
namespace filament {
namespace backend {
namespace metal {
static const auto cvBufferDeleter = [](const void* buffer) {
CVBufferRelease((CVMetalTextureRef) buffer);
@@ -300,6 +299,5 @@ id<MTLCommandBuffer> MetalExternalImage::encodeColorConversionPass(id<MTLTexture
return commandBuffer;
}
} // namespace metal
} // namespace backend
} // namespace filament
@@ -40,7 +40,6 @@
namespace filament {
namespace backend {
namespace metal {
class MetalSwapChain : public HwSwapChain {
public:
@@ -357,7 +356,6 @@ struct MetalTimerQuery : public HwTimerQuery {
std::shared_ptr<Status> status;
};
} // namespace metal
} // namespace backend
} // namespace filament
+7 -10
View File
@@ -32,7 +32,6 @@
namespace filament {
namespace backend {
namespace metal {
static inline MTLTextureUsage getMetalTextureUsage(TextureUsage usage) {
NSUInteger u = 0;
@@ -68,9 +67,8 @@ MetalSwapChain::MetalSwapChain(MetalContext& context, CAMetalLayer* nativeWindow
}
// Needed so we can use the SwapChain as a blit source.
if (flags & SwapChain::CONFIG_READABLE) {
nativeWindow.framebufferOnly = NO;
}
// Also needed for rendering directly into the SwapChain during refraction.
nativeWindow.framebufferOnly = NO;
layer.device = context.device;
}
@@ -81,7 +79,7 @@ MetalSwapChain::MetalSwapChain(MetalContext& context, int32_t width, int32_t hei
MetalSwapChain::MetalSwapChain(MetalContext& context, CVPixelBufferRef pixelBuffer, uint64_t flags)
: context(context), externalImage(context), type(SwapChainType::CVPIXELBUFFERREF) {
assert_invariant(flags & backend::SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER);
assert_invariant(flags & SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER);
MetalExternalImage::assertWritableImage(pixelBuffer);
externalImage.set(pixelBuffer);
assert_invariant(externalImage.isValid());
@@ -224,7 +222,7 @@ void MetalSwapChain::scheduleFrameScheduledCallback() {
}
assert_invariant(drawable);
backend::FrameScheduledCallback callback = frameScheduledCallback;
FrameScheduledCallback callback = frameScheduledCallback;
// This block strongly captures drawable to keep it alive until the handler executes.
// We cannot simply reference this->drawable inside the block because the block would then only
// capture the _this_ pointer (MetalSwapChain*) instead of the drawable.
@@ -245,12 +243,12 @@ void MetalSwapChain::scheduleFrameCompletedCallback() {
return;
}
backend::FrameCompletedCallback callback = frameCompletedCallback;
FrameCompletedCallback callback = frameCompletedCallback;
void* userData = frameCompletedUserData;
[getPendingCommandBuffer(&context) addCompletedHandler:^(id<MTLCommandBuffer> cb) {
struct CallbackData {
void* userData;
backend::FrameCompletedCallback callback;
FrameCompletedCallback callback;
};
CallbackData* data = new CallbackData();
data->userData = userData;
@@ -369,7 +367,7 @@ MetalProgram::MetalProgram(id<MTLDevice> device, const Program& program) noexcep
*shaderFunctions[i] = [library newFunctionWithName:@"main0"];
}
// All stages of the program have compiled successfuly, this is a valid program.
// All stages of the program have compiled successfully, this is a valid program.
isValid = true;
// This calculates Metal resource binding indices. Filament's sampler bindings range from 0-31
@@ -1024,6 +1022,5 @@ FenceStatus MetalFence::wait(uint64_t timeoutNs) {
return FenceStatus::ERROR;
}
} // namespace metal
} // namespace backend
} // namespace filament
@@ -20,7 +20,6 @@
namespace filament {
namespace backend {
namespace metal {
bool MetalResourceTracker::trackResource(CommandBuffer buffer, Resource resource,
ResourceDeleter deleter) {
@@ -53,6 +52,5 @@ void MetalResourceTracker::clearResources(CommandBuffer buffer) {
mResources.erase(found);
}
} // namespace metal
} // namespace backend
} // namespace filament
@@ -25,7 +25,6 @@
namespace filament {
namespace backend {
namespace metal {
/**
* MetalResourceTracker is a simple utility that maps individual command buffers to a set of
@@ -76,7 +75,6 @@ private:
std::mutex mMutex;
};
} // namespace metal
} // namespace backend
} // namespace filament
+13 -17
View File
@@ -31,24 +31,21 @@
namespace filament {
namespace backend {
inline bool operator==(const backend::SamplerParams& lhs, const backend::SamplerParams& rhs) {
inline bool operator==(const SamplerParams& lhs, const SamplerParams& rhs) {
return lhs.u == rhs.u;
}
namespace metal {
static constexpr uint32_t MAX_VERTEX_ATTRIBUTE_COUNT = backend::MAX_VERTEX_ATTRIBUTE_COUNT;
static constexpr uint32_t SAMPLER_GROUP_COUNT = Program::BINDING_COUNT;
static constexpr uint32_t SAMPLER_BINDING_COUNT = backend::MAX_SAMPLER_COUNT;
static constexpr uint32_t SAMPLER_BINDING_COUNT = MAX_SAMPLER_COUNT;
static constexpr uint32_t VERTEX_BUFFER_START = Program::BINDING_COUNT;
// The "zero" buffer is a small buffer for missing attributes that resides in the vertex slot
// immediately following any user-provided vertex buffers.
static constexpr uint32_t ZERO_VERTEX_BUFFER = backend::MAX_VERTEX_BUFFER_COUNT;
static constexpr uint32_t ZERO_VERTEX_BUFFER = MAX_VERTEX_BUFFER_COUNT;
// The total number of vertex buffer "slots" that the Metal backend can bind.
// + 1 to account for the zero buffer.
static constexpr uint32_t VERTEX_BUFFER_COUNT = backend::MAX_VERTEX_BUFFER_COUNT + 1;
static constexpr uint32_t VERTEX_BUFFER_COUNT = MAX_VERTEX_BUFFER_COUNT + 1;
// Forward declarations necessary here, definitions at end of file.
inline bool operator==(const MTLViewport& lhs, const MTLViewport& rhs);
@@ -173,7 +170,7 @@ private:
};
// StateTracker keeps track of state changes made to a Metal command encoder.
// Different kinds of state, like pipeline state, uniform buffer state, etc, are passed to the
// Different kinds of state, like pipeline state, uniform buffer state, etc., are passed to the
// current Metal command encoder and persist throughout the lifetime of the encoder (a frame).
// StateTracker is used to prevent calling redundant state change methods.
template<typename StateType>
@@ -212,7 +209,7 @@ private:
// Pipeline state
struct PipelineState {
struct MetalPipelineState {
id<MTLFunction> vertexFunction = nil; // 8 bytes
id<MTLFunction> fragmentFunction = nil; // 8 bytes
VertexDescription vertexDescription; // 528 bytes
@@ -223,7 +220,7 @@ struct PipelineState {
bool colorWrite = true; // 1 byte
char padding[7] = { 0 }; // 7 bytes
bool operator==(const PipelineState& rhs) const noexcept {
bool operator==(const MetalPipelineState& rhs) const noexcept {
return (
this->vertexFunction == rhs.vertexFunction &&
this->fragmentFunction == rhs.fragmentFunction &&
@@ -237,23 +234,23 @@ struct PipelineState {
);
}
bool operator!=(const PipelineState& rhs) const noexcept {
bool operator!=(const MetalPipelineState& rhs) const noexcept {
return !operator==(rhs);
}
};
// This assert checks that the struct is the size we expect without any "hidden" padding bytes
// inserted by the compiler.
static_assert(sizeof(PipelineState) == 688, "PipelineState unexpected size.");
static_assert(sizeof(MetalPipelineState) == 688, "MetalPipelineState unexpected size.");
struct PipelineStateCreator {
id<MTLRenderPipelineState> operator()(id<MTLDevice> device, const PipelineState& state)
id<MTLRenderPipelineState> operator()(id<MTLDevice> device, const MetalPipelineState& state)
noexcept;
};
using PipelineStateTracker = StateTracker<PipelineState>;
using PipelineStateTracker = StateTracker<MetalPipelineState>;
using PipelineStateCache = StateCache<PipelineState, id<MTLRenderPipelineState>,
using PipelineStateCache = StateCache<MetalPipelineState, id<MTLRenderPipelineState>,
PipelineStateCreator>;
// Depth-stencil State
@@ -315,7 +312,7 @@ using UniformBufferStateTracker = StateTracker<UniformBufferState>;
// Sampler states
struct SamplerState {
backend::SamplerParams samplerParams;
SamplerParams samplerParams;
uint32_t minLod = 0;
uint32_t maxLod = UINT_MAX;
@@ -343,7 +340,6 @@ using SamplerStateCache = StateCache<SamplerState, id<MTLSamplerState>, SamplerS
using CullModeStateTracker = StateTracker<MTLCullMode>;
using WindingStateTracker = StateTracker<MTLWinding>;
} // namespace metal
} // namespace backend
} // namespace filament
+2 -4
View File
@@ -20,10 +20,9 @@
namespace filament {
namespace backend {
namespace metal {
id<MTLRenderPipelineState> PipelineStateCreator::operator()(id<MTLDevice> device,
const PipelineState& state) noexcept {
const MetalPipelineState& state) noexcept {
MTLRenderPipelineDescriptor* descriptor = [MTLRenderPipelineDescriptor new];
// Shader Functions
@@ -105,7 +104,7 @@ id<MTLDepthStencilState> DepthStateCreator::operator()(id<MTLDevice> device,
id<MTLSamplerState> SamplerStateCreator::operator()(id<MTLDevice> device,
const SamplerState& state) noexcept {
backend::SamplerParams params = state.samplerParams;
SamplerParams params = state.samplerParams;
MTLSamplerDescriptor* samplerDescriptor = [MTLSamplerDescriptor new];
samplerDescriptor.minFilter = getFilter(params.filterMin);
samplerDescriptor.magFilter = getFilter(params.filterMag);
@@ -133,6 +132,5 @@ id<MTLSamplerState> SamplerStateCreator::operator()(id<MTLDevice> device,
return [device newSamplerStateWithDescriptor:samplerDescriptor];
}
} // namespace metal
} // namespace backend
} // namespace filament
+5 -7
View File
@@ -23,14 +23,13 @@
namespace filament {
namespace backend {
namespace metal {
struct MetalTimerQuery;
struct MetalContext;
class TimerQueryInterface {
class MetalTimerQueryInterface {
public:
virtual ~TimerQueryInterface();
virtual ~MetalTimerQueryInterface();
virtual void beginTimeElapsedQuery(MetalTimerQuery* query) = 0;
virtual void endTimeElapsedQuery(MetalTimerQuery* query) = 0;
virtual bool getQueryResult(MetalTimerQuery* query, uint64_t* outElapsedTime) = 0;
@@ -41,9 +40,9 @@ protected:
// Uses MTLSharedEvents to implement timer queries.
// Only available on >= iOS 12.0.
class API_AVAILABLE(ios(12.0)) TimerQueryFence : public TimerQueryInterface {
class API_AVAILABLE(ios(12.0)) MetalTimerQueryFence : public MetalTimerQueryInterface {
public:
explicit TimerQueryFence(MetalContext& context) : mContext(context) {}
explicit MetalTimerQueryFence(MetalContext& context) : mContext(context) {}
void beginTimeElapsedQuery(MetalTimerQuery* query) override;
void endTimeElapsedQuery(MetalTimerQuery* query) override;
@@ -53,14 +52,13 @@ private:
MetalContext& mContext;
};
class TimerQueryNoop : public TimerQueryInterface {
class TimerQueryNoop : public MetalTimerQueryInterface {
public:
void beginTimeElapsedQuery(MetalTimerQuery* query) override {}
void endTimeElapsedQuery(MetalTimerQuery* query) override {}
bool getQueryResult(MetalTimerQuery* query, uint64_t* outElapsedTime) override;
};
} // namespace metal
} // namespace backend
} // namespace filament
@@ -20,11 +20,10 @@
namespace filament {
namespace backend {
namespace metal {
TimerQueryInterface::~TimerQueryInterface() = default;
MetalTimerQueryInterface::~MetalTimerQueryInterface() = default;
void TimerQueryFence::beginTimeElapsedQuery(MetalTimerQuery* query) {
void MetalTimerQueryFence::beginTimeElapsedQuery(MetalTimerQuery* query) {
auto* fence = new MetalFence(mContext);
fence->encode();
query->status->elapsed = 0;
@@ -41,7 +40,7 @@ void TimerQueryFence::beginTimeElapsedQuery(MetalTimerQuery* query) {
});
}
void TimerQueryFence::endTimeElapsedQuery(MetalTimerQuery* query) {
void MetalTimerQueryFence::endTimeElapsedQuery(MetalTimerQuery* query) {
auto* fence = new MetalFence(mContext);
fence->encode();
@@ -57,7 +56,7 @@ void TimerQueryFence::endTimeElapsedQuery(MetalTimerQuery* query) {
});
}
bool TimerQueryFence::getQueryResult(MetalTimerQuery* query, uint64_t* outElapsedTime) {
bool MetalTimerQueryFence::getQueryResult(MetalTimerQuery* query, uint64_t* outElapsedTime) {
if (!query->status->available.load()) {
return false;
}
@@ -71,6 +70,5 @@ bool TimerQueryNoop::getQueryResult(MetalTimerQuery* query, uint64_t* outElapsed
return false;
}
} // namespace metal
} // namespace backend
} // namespace filament
+2 -2
View File
@@ -19,7 +19,7 @@
#include <Metal/Metal.h>
namespace filament::backend::metal {
namespace filament::backend {
/**
* Creates a texture view of the passed-in texture with the given swizzle. If swizzle is the default
@@ -42,6 +42,6 @@ id<MTLTexture> createTextureViewWithSwizzle(id<MTLTexture> texture,
*/
id<MTLTexture> createTextureViewWithSingleSlice(id<MTLTexture> texture, NSUInteger slice);
} // namespace filament::backend::metal
} // namespace filament::backend
#endif //TNT_FILAMENT_DRIVER_METALUTILS_H
+2 -2
View File
@@ -16,7 +16,7 @@
#include "MetalUtils.h"
namespace filament::backend::metal {
namespace filament::backend {
id<MTLTexture> createTextureViewWithSwizzle(id<MTLTexture> texture,
MTLTextureSwizzleChannels swizzle) {
@@ -48,4 +48,4 @@ id<MTLTexture> createTextureViewWithSingleSlice(id<MTLTexture> texture, NSUInteg
slices:NSMakeRange(slice, 1)];
}
}
} // namespace filament::backend
+15 -19
View File
@@ -17,20 +17,21 @@
#include "noop/NoopDriver.h"
#include "CommandStreamDispatcher.h"
namespace filament {
using namespace backend;
namespace filament::backend {
Driver* NoopDriver::create() {
return new NoopDriver();
}
NoopDriver::NoopDriver() noexcept : DriverBase(new ConcreteDispatcher<NoopDriver>()) {
}
NoopDriver::NoopDriver() noexcept = default;
NoopDriver::~NoopDriver() noexcept = default;
backend::ShaderModel NoopDriver::getShaderModel() const noexcept {
Dispatcher NoopDriver::getDispatcher() const noexcept {
return ConcreteDispatcher<NoopDriver>::make();
}
ShaderModel NoopDriver::getShaderModel() const noexcept {
#if defined(__ANDROID__) || defined(IOS) || defined(__EMSCRIPTEN__)
return ShaderModel::GL_ES_30;
#else
@@ -39,7 +40,7 @@ backend::ShaderModel NoopDriver::getShaderModel() const noexcept {
}
// explicit instantiation of the Dispatcher
template class backend::ConcreteDispatcher<NoopDriver>;
template class ConcreteDispatcher<NoopDriver>;
void NoopDriver::terminate() {
@@ -52,12 +53,12 @@ void NoopDriver::beginFrame(int64_t monotonic_clock_ns, uint32_t frameId) {
}
void NoopDriver::setFrameScheduledCallback(Handle<HwSwapChain> sch,
backend::FrameScheduledCallback callback, void* user) {
FrameScheduledCallback callback, void* user) {
}
void NoopDriver::setFrameCompletedCallback(Handle<HwSwapChain> sch,
backend::FrameCompletedCallback callback, void* user) {
FrameCompletedCallback callback, void* user) {
}
@@ -118,7 +119,7 @@ Handle<HwStream> NoopDriver::createStreamAcquired() {
}
void NoopDriver::setAcquiredImage(Handle<HwStream> sh, void* image,
backend::CallbackHandler* handler, backend::StreamCallback cb, void* userData) {
CallbackHandler* handler, StreamCallback cb, void* userData) {
}
void NoopDriver::setStreamDimensions(Handle<HwStream> sh, uint32_t width, uint32_t height) {
@@ -148,7 +149,7 @@ bool NoopDriver::isTextureSwizzleSupported() {
return true;
}
bool NoopDriver::isTextureFormatMipmappable(backend::TextureFormat format) {
bool NoopDriver::isTextureFormatMipmappable(TextureFormat format) {
return true;
}
@@ -181,7 +182,7 @@ math::float2 NoopDriver::getClipSpaceParams() {
}
uint8_t NoopDriver::getMaxDrawBuffers() {
return backend::MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT;
return MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT;
}
void NoopDriver::updateIndexBuffer(Handle<HwIndexBuffer> ibh, BufferDescriptor&& p,
@@ -307,14 +308,9 @@ void NoopDriver::readPixels(Handle<HwRenderTarget> src,
scheduleDestroy(std::move(p));
}
void NoopDriver::readStreamPixels(Handle<HwStream> sh, uint32_t x, uint32_t y, uint32_t width,
uint32_t height, PixelBufferDescriptor&& p) {
scheduleDestroy(std::move(p));
}
void NoopDriver::blit(TargetBufferFlags buffers,
Handle<HwRenderTarget> dst, backend::Viewport dstRect,
Handle<HwRenderTarget> src, backend::Viewport srcRect,
Handle<HwRenderTarget> dst, Viewport dstRect,
Handle<HwRenderTarget> src, Viewport srcRect,
SamplerMagFilter filter) {
}
+9 -8
View File
@@ -14,32 +14,33 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_NOOPDRIVER_H
#define TNT_FILAMENT_DRIVER_NOOPDRIVER_H
#ifndef TNT_FILAMENT_BACKEND_NOOPDRIVER_H
#define TNT_FILAMENT_BACKEND_NOOPDRIVER_H
#include "private/backend/Driver.h"
#include "DriverBase.h"
#include <utils/compiler.h>
namespace filament {
namespace filament::backend {
class NoopDriver final : public backend::DriverBase {
class NoopDriver final : public DriverBase {
NoopDriver() noexcept;
~NoopDriver() noexcept override;
Dispatcher getDispatcher() const noexcept final;
public:
static backend::Driver* create();
static Driver* create();
private:
backend::ShaderModel getShaderModel() const noexcept final;
ShaderModel getShaderModel() const noexcept final;
/*
* Driver interface
*/
template<typename T>
friend class backend::ConcreteDispatcher;
friend class ConcreteDispatcher;
#define DECL_DRIVER_API(methodName, paramsDecl, params) \
UTILS_ALWAYS_INLINE inline void methodName(paramsDecl);
@@ -57,4 +58,4 @@ private:
} // namespace filament
#endif // TNT_FILAMENT_DRIVER_NOOPDRIVER_H
#endif // TNT_FILAMENT_BACKEND_NOOPDRIVER_H
+2 -2
View File
@@ -18,9 +18,9 @@
#include "noop/NoopDriver.h"
namespace filament {
namespace filament::backend {
backend::Driver* PlatformNoop::createDriver(void* const sharedGLContext) noexcept {
Driver* PlatformNoop::createDriver(void* const sharedGLContext) noexcept {
return NoopDriver::create();
}
+6 -6
View File
@@ -14,15 +14,15 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_NOOP_PLATFORM_NOOP_H
#define TNT_FILAMENT_DRIVER_NOOP_PLATFORM_NOOP_H
#ifndef TNT_FILAMENT_BACKEND_NOOP_PLATFORM_NOOP_H
#define TNT_FILAMENT_BACKEND_NOOP_PLATFORM_NOOP_H
#include <backend/DriverEnums.h>
#include <backend/Platform.h>
namespace filament {
namespace filament::backend {
class PlatformNoop final : public backend::DefaultPlatform {
class PlatformNoop final : public DefaultPlatform {
public:
int getOSVersion() const noexcept final { return 0; }
@@ -31,9 +31,9 @@ public:
protected:
backend::Driver* createDriver(void* sharedContext) noexcept override;
Driver* createDriver(void* sharedContext) noexcept override;
};
} // namespace filament
#endif // TNT_FILAMENT_DRIVER_NOOP_PLATFORM_NOOP_H
#endif // TNT_FILAMENT_BACKEND_NOOP_PLATFORM_NOOP_H
+18 -2
View File
@@ -20,7 +20,7 @@
#include "private/backend/Driver.h"
namespace filament {
namespace filament::backend {
using namespace backend;
using namespace utils;
@@ -121,5 +121,21 @@ void assertFramebufferStatus(io::ostream& out, GLenum target, const char* functi
}
}
bool unordered_string_set::has(std::string_view str) const noexcept {
return find(str) != end();
}
unordered_string_set split(const char* extensions) noexcept {
unordered_string_set set;
std::string_view string(extensions);
do {
auto p = string.find(' ');
p = (p == std::string_view::npos ? string.length() : p);
set.emplace(string.data(), p);
string.remove_prefix(p == string.length() ? p : p + 1);
} while(!string.empty());
return set;
}
} // namespace GLUtils
} // namespace filament
} // namespace filament::backend
+50 -66
View File
@@ -14,22 +14,22 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_GLUTILS_H
#define TNT_FILAMENT_DRIVER_GLUTILS_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_GLUTILS_H
#define TNT_FILAMENT_BACKEND_OPENGL_GLUTILS_H
#include <utils/compiler.h>
#include <utils/Log.h>
#include <backend/DriverEnums.h>
#include <string>
#include <string_view>
#include <unordered_set>
#include <string.h>
#include "gl_headers.h"
namespace filament {
namespace filament::backend {
namespace GLUtils {
const char* getGLError(GLenum error) noexcept;
@@ -42,17 +42,16 @@ void assertFramebufferStatus(utils::io::ostream& out, GLenum target, const char*
#ifdef NDEBUG
# define CHECK_GL_ERROR(out)
# define CHECK_GL_ERROR_NON_FATAL(out)
# define CHECK_GL_FRAMEBUFFER_STATUS(out, target)
#else
# ifdef _MSC_VER
# define __PRETTY_FUNCTION__ __FUNCSIG__
# endif
# define CHECK_GL_ERROR(out) { GLUtils::assertGLError(out, __PRETTY_FUNCTION__, __LINE__); }
# define CHECK_GL_FRAMEBUFFER_STATUS(out, target) { GLUtils::checkFramebufferStatus(out, target, __PRETTY_FUNCTION__, __LINE__); }
# define CHECK_GL_ERROR(out) { GLUtils::assertGLError(out, __func__, __LINE__); }
# define CHECK_GL_ERROR_NON_FATAL(out) { GLUtils::checkGLError(out, __func__, __LINE__); }
# define CHECK_GL_FRAMEBUFFER_STATUS(out, target) { GLUtils::checkFramebufferStatus(out, target, __func__, __LINE__); }
#endif
constexpr inline GLuint getComponentCount(backend::ElementType type) noexcept {
using ElementType = backend::ElementType;
constexpr inline GLuint getComponentCount(ElementType type) noexcept {
using ElementType = ElementType;
switch (type) {
case ElementType::BYTE:
case ElementType::UBYTE:
@@ -91,35 +90,35 @@ constexpr inline GLuint getComponentCount(backend::ElementType type) noexcept {
// Our enums to GLenum conversions
// ------------------------------------------------------------------------------------------------
constexpr inline GLbitfield getAttachmentBitfield(backend::TargetBufferFlags flags) noexcept {
constexpr inline GLbitfield getAttachmentBitfield(TargetBufferFlags flags) noexcept {
GLbitfield mask = 0;
if (any(flags & backend::TargetBufferFlags::COLOR_ALL)) {
if (any(flags & TargetBufferFlags::COLOR_ALL)) {
mask |= (GLbitfield)GL_COLOR_BUFFER_BIT;
}
if (any(flags & backend::TargetBufferFlags::DEPTH)) {
if (any(flags & TargetBufferFlags::DEPTH)) {
mask |= (GLbitfield)GL_DEPTH_BUFFER_BIT;
}
if (any(flags & backend::TargetBufferFlags::STENCIL)) {
if (any(flags & TargetBufferFlags::STENCIL)) {
mask |= (GLbitfield)GL_STENCIL_BUFFER_BIT;
}
return mask;
}
constexpr inline GLenum getBufferUsage(backend::BufferUsage usage) noexcept {
constexpr inline GLenum getBufferUsage(BufferUsage usage) noexcept {
switch (usage) {
case backend::BufferUsage::STATIC:
case BufferUsage::STATIC:
return GL_STATIC_DRAW;
case backend::BufferUsage::DYNAMIC:
case backend::BufferUsage::STREAM:
case BufferUsage::DYNAMIC:
case BufferUsage::STREAM:
return GL_DYNAMIC_DRAW;
}
}
constexpr inline GLenum getBufferBindingType(backend::BufferObjectBinding bindingType) noexcept {
constexpr inline GLenum getBufferBindingType(BufferObjectBinding bindingType) noexcept {
switch (bindingType) {
case backend::BufferObjectBinding::VERTEX:
case BufferObjectBinding::VERTEX:
return GL_ARRAY_BUFFER;
case backend::BufferObjectBinding::UNIFORM:
case BufferObjectBinding::UNIFORM:
return GL_UNIFORM_BUFFER;
}
}
@@ -128,8 +127,8 @@ constexpr inline GLboolean getNormalization(bool normalized) noexcept {
return GLboolean(normalized ? GL_TRUE : GL_FALSE);
}
constexpr inline GLenum getComponentType(backend::ElementType type) noexcept {
using ElementType = backend::ElementType;
constexpr inline GLenum getComponentType(ElementType type) noexcept {
using ElementType = ElementType;
switch (type) {
case ElementType::BYTE:
case ElementType::BYTE2:
@@ -173,8 +172,8 @@ constexpr inline GLenum getCubemapTarget(uint16_t layer) noexcept {
return GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
}
constexpr inline GLenum getWrapMode(backend::SamplerWrapMode mode) noexcept {
using SamplerWrapMode = backend::SamplerWrapMode;
constexpr inline GLenum getWrapMode(SamplerWrapMode mode) noexcept {
using SamplerWrapMode = SamplerWrapMode;
switch (mode) {
case SamplerWrapMode::REPEAT:
return GL_REPEAT;
@@ -185,8 +184,8 @@ constexpr inline GLenum getWrapMode(backend::SamplerWrapMode mode) noexcept {
}
}
constexpr inline GLenum getTextureFilter(backend::SamplerMinFilter filter) noexcept {
using SamplerMinFilter = backend::SamplerMinFilter;
constexpr inline GLenum getTextureFilter(SamplerMinFilter filter) noexcept {
using SamplerMinFilter = SamplerMinFilter;
switch (filter) {
case SamplerMinFilter::NEAREST:
case SamplerMinFilter::LINEAR:
@@ -200,13 +199,13 @@ constexpr inline GLenum getTextureFilter(backend::SamplerMinFilter filter) noexc
}
}
constexpr inline GLenum getTextureFilter(backend::SamplerMagFilter filter) noexcept {
constexpr inline GLenum getTextureFilter(SamplerMagFilter filter) noexcept {
return GL_NEAREST + GLenum(filter);
}
constexpr inline GLenum getBlendEquationMode(backend::BlendEquation mode) noexcept {
using BlendEquation = backend::BlendEquation;
constexpr inline GLenum getBlendEquationMode(BlendEquation mode) noexcept {
using BlendEquation = BlendEquation;
switch (mode) {
case BlendEquation::ADD: return GL_FUNC_ADD;
case BlendEquation::SUBTRACT: return GL_FUNC_SUBTRACT;
@@ -216,8 +215,8 @@ constexpr inline GLenum getBlendEquationMode(backend::BlendEquation mode) noexce
}
}
constexpr inline GLenum getBlendFunctionMode(backend::BlendFunction mode) noexcept {
using BlendFunction = backend::BlendFunction;
constexpr inline GLenum getBlendFunctionMode(BlendFunction mode) noexcept {
using BlendFunction = BlendFunction;
switch (mode) {
case BlendFunction::ZERO: return GL_ZERO;
case BlendFunction::ONE: return GL_ONE;
@@ -233,13 +232,13 @@ constexpr inline GLenum getBlendFunctionMode(backend::BlendFunction mode) noexce
}
}
constexpr inline GLenum getTextureCompareMode(backend::SamplerCompareMode mode) noexcept {
return mode == backend::SamplerCompareMode::NONE ?
constexpr inline GLenum getTextureCompareMode(SamplerCompareMode mode) noexcept {
return mode == SamplerCompareMode::NONE ?
GL_NONE : GL_COMPARE_REF_TO_TEXTURE;
}
constexpr inline GLenum getTextureCompareFunc(backend::SamplerCompareFunc func) noexcept {
using SamplerCompareFunc = backend::SamplerCompareFunc;
constexpr inline GLenum getTextureCompareFunc(SamplerCompareFunc func) noexcept {
using SamplerCompareFunc = SamplerCompareFunc;
switch (func) {
case SamplerCompareFunc::LE: return GL_LEQUAL;
case SamplerCompareFunc::GE: return GL_GEQUAL;
@@ -252,12 +251,12 @@ constexpr inline GLenum getTextureCompareFunc(backend::SamplerCompareFunc func)
}
}
constexpr inline GLenum getDepthFunc(backend::SamplerCompareFunc func) noexcept {
constexpr inline GLenum getDepthFunc(SamplerCompareFunc func) noexcept {
return getTextureCompareFunc(func);
}
constexpr inline GLenum getFormat(backend::PixelDataFormat format) noexcept {
using PixelDataFormat = backend::PixelDataFormat;
constexpr inline GLenum getFormat(PixelDataFormat format) noexcept {
using PixelDataFormat = PixelDataFormat;
switch (format) {
case PixelDataFormat::R: return GL_RED;
case PixelDataFormat::R_INTEGER: return GL_RED_INTEGER;
@@ -274,8 +273,8 @@ constexpr inline GLenum getFormat(backend::PixelDataFormat format) noexcept {
}
}
constexpr inline GLenum getType(backend::PixelDataType type) noexcept {
using PixelDataType = backend::PixelDataType;
constexpr inline GLenum getType(PixelDataType type) noexcept {
using PixelDataType = PixelDataType;
switch (type) {
case PixelDataType::UBYTE: return GL_UNSIGNED_BYTE;
case PixelDataType::BYTE: return GL_BYTE;
@@ -292,8 +291,8 @@ constexpr inline GLenum getType(backend::PixelDataType type) noexcept {
}
}
constexpr inline GLenum getSwizzleChannel(backend::TextureSwizzle c) noexcept {
using TextureSwizzle = backend::TextureSwizzle;
constexpr inline GLenum getSwizzleChannel(TextureSwizzle c) noexcept {
using TextureSwizzle = TextureSwizzle;
switch (c) {
case TextureSwizzle::SUBSTITUTE_ZERO:
return GL_ZERO;
@@ -313,8 +312,8 @@ constexpr inline GLenum getSwizzleChannel(backend::TextureSwizzle c) noexcept {
// clang looses it on this one, and generates a huge jump table when
// inlined. So we don't mark it as inline (only constexpr) which solves the problem,
// strangely, when not inlined, clang simply generates an array lookup.
constexpr /* inline */ GLenum getInternalFormat(backend::TextureFormat format) noexcept {
using TextureFormat = backend::TextureFormat;
constexpr /* inline */ GLenum getInternalFormat(TextureFormat format) noexcept {
using TextureFormat = TextureFormat;
switch (format) {
// 8-bits per element
case TextureFormat::R8: return GL_R8;
@@ -507,29 +506,14 @@ constexpr /* inline */ GLenum getInternalFormat(backend::TextureFormat format) n
}
}
class unordered_string_set : public std::unordered_set<std::string> {
class unordered_string_set : public std::unordered_set<std::string_view> {
public:
bool has(const char* str) {
return find(std::string(str)) != end();
}
bool has(std::string_view str) const noexcept;
};
inline unordered_string_set split(const char* spacedList) {
unordered_string_set set;
const char* current = spacedList;
const char* head = current;
do {
head = strchr(current, ' ');
std::string s(current, head ? head - current : strlen(current));
if (s.length()) {
set.insert(std::move(s));
}
current = head + 1;
} while (head);
return set;
}
unordered_string_set split(const char* extensions) noexcept;
} // namespace GLUtils
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_GLUTILS_H
#endif // TNT_FILAMENT_BACKEND_OPENGL_GLUTILS_H
+5 -5
View File
@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_NULLGLES_H
#define TNT_FILAMENT_DRIVER_NULLGLES_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_NULLGLES_H
#define TNT_FILAMENT_BACKEND_OPENGL_NULLGLES_H
/*
* This is used for debugging (stubbing out GLES calls)
@@ -27,7 +27,7 @@
*
*/
namespace filament {
namespace filament::backend {
namespace nullgles {
inline void glScissor(GLint, GLint, GLsizei, GLsizei) { }
@@ -81,6 +81,6 @@ inline GLenum glGetError() { return GL_NO_ERROR; }
// turn GLES calls defined above into no-ops
//using namespace nullgles;
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_NULLGLES_H
#endif // TNT_FILAMENT_BACKEND_OPENGL_NULLGLES_H
@@ -1,215 +0,0 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "OpenGLBlitter.h"
#include "GLUtils.h"
#include "OpenGLContext.h"
#include <utils/compiler.h>
#include <utils/Log.h>
#include <math/vec2.h>
using namespace filament::math;
using namespace utils;
namespace filament {
static const char s_vertexES[] = R"SHADER(#version 300 es
in vec4 pos;
void main() {
gl_Position = pos;
}
)SHADER";
static const char s_vertexGL[] = R"SHADER(#version 410 core
in vec4 pos;
void main() {
gl_Position = pos;
}
)SHADER";
static const char s_fragmentES[] = R"SHADER(#version 300 es
#extension GL_OES_EGL_image_external_essl3 : enable
precision mediump float;
uniform samplerExternalOES sampler;
out vec4 fragColor;
void main() {
fragColor = texelFetch(sampler, ivec2(gl_FragCoord.xy), 0);
}
)SHADER";
static const char s_fragmentGL[] = R"SHADER(#version 410 core
precision mediump float;
uniform sampler2D sampler;
out vec4 fragColor;
void main() {
fragColor = texelFetch(sampler, ivec2(gl_FragCoord.xy), 0);
}
)SHADER";
void OpenGLBlitter::init() noexcept {
glGenSamplers(1, &mSampler);
glSamplerParameteri(mSampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glSamplerParameteri(mSampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glSamplerParameteri(mSampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glSamplerParameteri(mSampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
GLint status;
char const* vsource[2] = { s_vertexES, s_vertexGL };
char const* fsource[2] = { s_fragmentES, s_fragmentGL };
const size_t index = GLES30_HEADERS ? 0 : 1;
mVertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(mVertexShader, 1, vsource + index, nullptr);
glCompileShader(mVertexShader);
glGetShaderiv(mVertexShader, GL_COMPILE_STATUS, &status);
assert_invariant(status == GL_TRUE);
mFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(mFragmentShader, 1, fsource + index, nullptr);
glCompileShader(mFragmentShader);
glGetShaderiv(mFragmentShader, GL_COMPILE_STATUS, &status);
assert_invariant(status == GL_TRUE);
mProgram = glCreateProgram();
glAttachShader(mProgram, mVertexShader);
glAttachShader(mProgram, mFragmentShader);
glLinkProgram(mProgram);
glGetProgramiv(mProgram, GL_LINK_STATUS, &status);
assert_invariant(status == GL_TRUE);
glUseProgram(mProgram);
GLint loc = glGetUniformLocation(mProgram, "sampler");
GLuint tmu = 0;
glUniform1i(loc, tmu);
glGenFramebuffers(1, &mFBO);
CHECK_GL_ERROR(utils::slog.e)
}
void OpenGLBlitter::terminate() noexcept {
glDeleteSamplers(1, &mSampler);
glDetachShader(mProgram, mVertexShader);
glDetachShader(mProgram, mFragmentShader);
glDeleteShader(mVertexShader);
glDeleteShader(mFragmentShader);
glDeleteProgram(mProgram);
glDeleteFramebuffers(1, &mFBO);
}
void OpenGLBlitter::blit(GLuint srcTextureExternal, GLuint dstTexture2d, GLuint w, GLuint h) noexcept {
const float2 vtx[3] = {{ -1.0f, 3.0f },
{ -1.0f, -1.0f },
{ 3.0f, -1.0f }};
// we're using tmu 0 as the source texture
GLuint tmu = 0;
// source texture
glBindSampler(tmu, mSampler);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, srcTextureExternal);
CHECK_GL_ERROR(utils::slog.e)
// destination texture
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstTexture2d, 0);
CHECK_GL_ERROR(utils::slog.e)
CHECK_GL_FRAMEBUFFER_STATUS(utils::slog.e, GL_FRAMEBUFFER)
// geometry
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vtx);
// blit...
glViewport(0, 0, w, h);
glUseProgram(mProgram);
glDrawArrays(GL_TRIANGLES, 0, 3);
CHECK_GL_ERROR(utils::slog.e)
}
void OpenGLBlitter::State::save() noexcept {
mHasState = true;
// TODO: technically we should also save glVertexAttribPointer
GLuint tmu = 0;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &framebuffer);
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &array);
glGetIntegerv(GL_CURRENT_PROGRAM, &program);
glGetIntegerv(GL_VIEWPORT, viewport);
glGetIntegerv(GL_COLOR_WRITEMASK, writeMask);
scissorTest = glIsEnabled(GL_SCISSOR_TEST);
stencilTest = glIsEnabled(GL_STENCIL_TEST);
cullFace = glIsEnabled(GL_CULL_FACE);
glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &vertexAttrib);
// save the current active texture first
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture);
// we're using tmu 0 as the source texture
glActiveTexture(GL_TEXTURE0 + tmu);
// save what depends on glActiveTexture
glGetIntegerv(GL_SAMPLER_BINDING, &sampler);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture);
/*
* Set the state
*/
// we're using tmu 0 as the source texture
glDisable(GL_SCISSOR_TEST);
glDisable(GL_STENCIL_TEST);
glDisable(GL_CULL_FACE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
CHECK_GL_ERROR(utils::slog.e)
}
void OpenGLBlitter::State::restore() noexcept {
GLuint tmu = 0;
glColorMask(
(GLboolean)writeMask[0],
(GLboolean)writeMask[1],
(GLboolean)writeMask[2],
(GLboolean)writeMask[3]);
if (cullFace) {
glEnable(GL_CULL_FACE);
}
if (stencilTest) {
glEnable(GL_STENCIL_TEST);
}
if (scissorTest) {
glEnable(GL_SCISSOR_TEST);
}
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
glUseProgram(static_cast<GLuint>(program));
glBindBuffer(GL_ARRAY_BUFFER, static_cast<GLuint>(array));
glBindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(framebuffer));
if (!vertexAttrib) {
glDisableVertexAttribArray(0);
}
glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(texture));
glBindSampler(tmu, static_cast<GLuint>(sampler));
glActiveTexture(static_cast<GLenum>(activeTexture));
CHECK_GL_ERROR(utils::slog.e)
}
} // namespace filament

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