Merge branch 'rc/1.56.8' into release

This commit is contained in:
Powei Feng
2025-02-06 11:14:08 -08:00
1781 changed files with 296025 additions and 2297 deletions
+14 -1
View File
@@ -77,9 +77,22 @@ jobs:
run: |
cd build/web && printf "y" | ./build.sh presubmit
validate-docs:
name: validate-docs
runs-on: ubuntu-22.04-4core
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- name: Check for manual edits to /docs
run: |
echo "${{ github.event.pull_request.head.sha }} -- ${{ github.event.pull_request.head.sha }}"
# disable for now
# bash docs_src/build/presubmit_check.sh ${{ github.event.pull_request.head.sha }}
test-renderdiff:
name: test-renderdiff
runs-on: ubuntu-22.04-32core
runs-on: ubuntu-22.04-16core
steps:
- uses: actions/checkout@v4.1.6
+11 -2
View File
@@ -457,10 +457,19 @@ if (NOT WEBGL)
set(GC_SECTIONS "-Wl,--gc-sections")
endif()
# Prevents stacks from being made for executable by explicitly adding this linker flag. Otherwise,
# it generates warnings newly introduced as of GNU LD 2.39. Modern security practices strongly
# recommend marking the stack as non-executable using the -z noexecstack linker flag to prevent
# stack-based buffer overflow exploits.
# See: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ffcf9c5700e49c0aee42dcba9a12ba21338e8136
if (LINUX)
set(NO_EXEC_STACK "-Wl,-z,noexecstack")
endif()
set(B_SYMBOLIC_FUNCTIONS "-Wl,-Bsymbolic-functions")
if (ANDROID)
set(BINARY_ALIGNMENT "-Wl,-z,max-page-size=16384")
set(BINARY_ALIGNMENT "-Wl,-z,max-page-size=16384")
endif()
if (APPLE)
@@ -475,7 +484,7 @@ if (APPLE)
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> qc -S <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GC_SECTIONS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GC_SECTIONS} ${NO_EXEC_STACK}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GC_SECTIONS} ${B_SYMBOLIC_FUNCTIONS} ${BINARY_ALIGNMENT}")
if (WEBGL_PTHREADS)
+14 -2
View File
@@ -121,9 +121,21 @@ private:
- other headers are sorted in reverse order of their layering, that is, lower layer headers last
- within a layer, headers are sorted alphabetically
- strive for implementing one class per file
- `STL` limited in public headers to:
- `type_traits`
- `STL` limited in **filament** public headers to:
- `array`
- `initializer_list`
- `iterator`
- `limits`
- `optional`
- `type_traits`
- `utility`
- `variant`
For **libfilament** the rule of thumb is that STL headers that don't generate code are allowed (e.g. `type_traits`),
conversely containers and algorithms are not allowed. There are exceptions such as `array`. See above for the full list.
- The following `STL` headers are banned entirely, from public and private headers as well as implementation files:
- `iostream`
*Sorting the headers is important to help catching missing `#include` directives.*
+2 -2
View File
@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.56.7'
implementation 'com.google.android.filament:filament-android:1.56.8'
}
```
@@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
iOS projects can use CocoaPods to install the latest release:
```shell
pod 'Filament', '~> 1.56.7'
pod 'Filament', '~> 1.56.8'
```
## Documentation
+3
View File
@@ -7,6 +7,9 @@ A new header is inserted each time a *tag* is created.
Instead, if you are authoring a PR for the main branch, add your release note to
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
## v1.56.8
## v1.56.7
@@ -392,11 +392,11 @@ Java_com_google_android_filament_Engine_nIsValidSwapChain(JNIEnv*, jclass,
return (jboolean)engine->isValid((SwapChain*)nativeSwapChain);
}
extern "C" JNIEXPORT void JNICALL
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nFlushAndWait(JNIEnv*, jclass,
jlong nativeEngine) {
jlong nativeEngine, jlong timeout) {
Engine* engine = (Engine*) nativeEngine;
engine->flushAndWait();
return engine->flushAndWait((uint64_t)timeout);
}
extern "C" JNIEXPORT void JNICALL
@@ -459,6 +459,13 @@ Java_com_google_android_filament_RenderableManager_nSetMaterialInstanceAt(JNIEnv
materialInstance);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nClearMaterialInstanceAt(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jint primitiveIndex) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
rm->clearMaterialInstanceAt((RenderableManager::Instance) i, (size_t) primitiveIndex);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_RenderableManager_nGetMaterialInstanceAt(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jint primitiveIndex) {
@@ -1271,7 +1271,28 @@ public class Engine {
* {@link android.view.SurfaceHolder.Callback#surfaceDestroyed surfaceDestroyed}.</p>
*/
public void flushAndWait() {
nFlushAndWait(getNativeObject());
boolean unused = flushAndWait(Fence.WAIT_FOR_EVER);
}
/**
* Kicks the hardware thread (e.g. the OpenGL, Vulkan or Metal thread) and blocks until
* all commands to this point are executed. Note that does guarantee that the
* hardware is actually finished.
*
* A timeout can be specified, if for some reason this flushAndWait doesn't complete before the timeout, it will
* return false, true otherwise.
*
* <p>This is typically used right after destroying the <code>SwapChain</code>,
* in cases where a guarantee about the <code>SwapChain</code> destruction is needed in a
* timely fashion, such as when responding to Android's
* <code>android.view.SurfaceHolder.Callback.surfaceDestroyed</code></p>
*
* @param timeout A timeout in nanoseconds
* @return true if successful, false if flushAndWait timed out, in which case it wasn't successful and commands
* might still be executing on both the CPU and GPU sides.
*/
public boolean flushAndWait(long timeout) {
return nFlushAndWait(getNativeObject(), timeout);
}
/**
@@ -1437,7 +1458,7 @@ public class Engine {
private static native boolean nIsValidRenderTarget(long nativeEngine, long nativeTarget);
private static native boolean nIsValidSwapChain(long nativeEngine, long nativeSwapChain);
private static native void nDestroyEntity(long nativeEngine, int entity);
private static native void nFlushAndWait(long nativeEngine);
private static native boolean nFlushAndWait(long nativeEngine, long timeout);
private static native void nFlush(long nativeEngine);
private static native boolean nIsPaused(long nativeEngine);
private static native void nSetPaused(long nativeEngine, boolean paused);
@@ -869,6 +869,13 @@ public class RenderableManager {
nSetMaterialInstanceAt(mNativeObject, i, primitiveIndex, materialInstance.getNativeObject());
}
/**
* Clears the material instance for the given primitive.
*/
public void clearMaterialInstanceAt(@EntityInstance int i, @IntRange(from = 0) int primitiveIndex) {
nClearMaterialInstanceAt(mNativeObject, i, primitiveIndex);
}
/**
* Creates a MaterialInstance Java wrapper object for a particular material instance.
*/
@@ -1012,6 +1019,7 @@ public class RenderableManager {
private static native void nGetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float[] center, float[] halfExtent);
private static native int nGetPrimitiveCount(long nativeRenderableManager, int i);
private static native void nSetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex, long nativeMaterialInstance);
private static native void nClearMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex);
private static native long nGetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex);
private static native void nSetGeometryAt(long nativeRenderableManager, int i, int primitiveIndex, int primitiveType, long nativeVertexBuffer, long nativeIndexBuffer, int offset, int count);
private static native void nSetBlendOrderAt(long nativeRenderableManager, int i, int primitiveIndex, int blendOrder);
@@ -1420,10 +1420,10 @@ public class View {
/**
* Upscaling quality
* LOW: bilinear filtered blit. Fastest, poor quality
* MEDIUM: AMD FidelityFX FSR1 w/ mobile optimizations
* MEDIUM: Qualcomm Snapdragon Game Super Resolution (SGSR) 1.0
* HIGH: AMD FidelityFX FSR1 w/ mobile optimizations
* ULTRA: AMD FidelityFX FSR1
* FSR1 require a well anti-aliased (MSAA or TAA), noise free scene.
* FSR1 and SGSR require a well anti-aliased (MSAA or TAA), noise free scene. Avoid FXAA and dithering.
*
* The default upscaling quality is set to LOW.
*/
+1 -1
View File
@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.56.7
VERSION_NAME=1.56.8
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
+7 -7
View File
@@ -1,16 +1,16 @@
#!/bin/bash
# version of clang we want to use
GITHUB_CLANG_VERSION=14
export GITHUB_CLANG_VERSION=14
# version of CMake to use instead of the default one
CMAKE_VERSION=3.19.5
export GITHUB_CMAKE_VERSION=3.19.5
# version of ninja to use
NINJA_VERSION=1.10.2
export GITHUB_NINJA_VERSION=1.10.2
# Steps for GitHub Workflows
if [[ "$GITHUB_WORKFLOW" ]]; then
# Install ninja
wget -q https://github.com/ninja-build/ninja/releases/download/v$NINJA_VERSION/ninja-linux.zip
wget -q https://github.com/ninja-build/ninja/releases/download/v$GITHUB_NINJA_VERSION/ninja-linux.zip
unzip -q ninja-linux.zip
export PATH="$PWD:$PATH"
@@ -18,9 +18,9 @@ if [[ "$GITHUB_WORKFLOW" ]]; then
mkdir -p cmake
cd cmake
sudo wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-Linux-x86_64.sh
sudo chmod +x ./cmake-$CMAKE_VERSION-Linux-x86_64.sh
sudo ./cmake-$CMAKE_VERSION-Linux-x86_64.sh --skip-license > /dev/null
sudo wget https://github.com/Kitware/CMake/releases/download/v$GITHUB_CMAKE_VERSION/cmake-$GITHUB_CMAKE_VERSION-Linux-x86_64.sh
sudo chmod +x ./cmake-$GITHUB_CMAKE_VERSION-Linux-x86_64.sh
sudo ./cmake-$GITHUB_CMAKE_VERSION-Linux-x86_64.sh --skip-license > /dev/null
sudo update-alternatives --install /usr/bin/cmake cmake $(pwd)/bin/cmake 1000 --force
cd ..
+140
View File
@@ -0,0 +1,140 @@
# Copyright (C) 2025 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This script contains several checks on the current commit, each corresponds to `possible_conditions`
# in the main function below
# - Direct (non-filamentbot) edits of /docs
# - Edits to sources of READMEs that are duplicated to /docs
# or edits to /docs_src sources
# - Commit message has DOCS_BYPASS
# - Commit message has DOCS_FORCE
# - Commit message has DOCS_ALLOW_DIRECT_EDITS
import json
import sys
import os
from utils import execute, ArgParseImpl
CUR_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT_DIR = os.path.join(CUR_DIR, '../../')
def get_last_commit_hash():
res, ret = execute('git rev-parse HEAD', cwd=ROOT_DIR)
assert res == 0, 'Failed to get the last commit hash'
return ret.strip()
def get_edited_files(commit_hash):
INSERT = '#####?????'
res, ret = execute(f'git show --name-only --pretty=%b{INSERT} {commit_hash}')
assert res == 0, 'Failed to get edited filed'
files = []
_, after = ret.split(INSERT)
for r in filter(lambda a: len(a) > 0, after.split('\n')):
if r.startswith('commit'):
break
files.append(r)
return files
# Returns True if there were no direct edits to '/docs'
def check_no_direct_edits(commit_hash, printing=True):
bad = [f'\t{f}' for f in get_edited_files(commit_hash) if f.startswith('docs/')]
if printing and len(bad) > 0:
print(f'Found edits to /docs:\n' + '\n'.join(bad))
return len(bad) == 0
# Returns True if docs sources have been modified
def check_has_source_edits(commit_hash, printing=True):
config = {}
with open(f'{CUR_DIR}/duplicates.json') as config_txt:
config = json.loads(config_txt.read())
source_files = set(config.keys())
edited_files = set(get_edited_files(commit_hash))
overlap = [f'\t{f}' for f in list(source_files & edited_files)]
if printing and len(overlap) > 0:
print(f'Found edited source files:\n' + '\n'.join(overlap))
return len(overlap) > 0
# Returns true in a given TAG is found in the commit msg
def commit_msg_has_tag(commit_hash, tag, printing=True):
res, ret = execute(f'git log --pretty=%B {commit_hash}', cwd=ROOT_DIR)
for l in ret.split('\n'):
if tag == l.strip():
if printing:
print(f'Found tag={tag} in commit message')
return True
return False
if __name__ == "__main__":
parser = ArgParseImpl()
TAG_DOCS_BYPASS = 'DOCS_BYPASS'
TAG_DOCS_FORCE = 'DOCS_FORCE'
TAG_DOCS_ALLOW_DIRECT_EDITS = 'DOCS_ALLOW_DIRECT_EDITS'
possible_conditions = {
'no_direct_edits':
check_no_direct_edits,
'source_edits':
check_has_source_edits,
'commit_docs_bypass':
lambda h: commit_msg_has_tag(h, TAG_DOCS_BYPASS),
'commit_docs_force':
lambda h: commit_msg_has_tag(h, TAG_DOCS_FORCE),
'commit_docs_allow_direct_edits':
lambda h: commit_msg_has_tag(h, TAG_DOCS_ALLOW_DIRECT_EDITS),
}
possible_str = ', '.join(list(possible_conditions.keys()))
parser.add_argument(
'--do-and',
type=str,
help=(
f'A conjunction of boolean conditions. Possible values are={possible_str}. '
'Negation is done with `-`'
)
)
parser.add_argument(
'--do-or',
type=str,
help=(
f'A disjunction of boolean conditions. Possible values are={possible_str}. '
'Negation is done with `-`'
)
)
args, _ = parser.parse_known_args(sys.argv[1:len(sys.argv) - 1])
commit_hash = sys.argv[-1]
assert not (args.do_and and args.do_or), "Must not supply both '--do-and' and '--do-or'"
assert args.do_and or args.do_or, "Must supply argument '--do-and' or '--do-or'"
conds = args.do_and.split(',') if args.do_and else args.do_or.split(',')
conds = [c.strip() for c in conds]
assert all(
[c in possible_conditions.keys() for c in
[(c.replace('-', '') if c.startswith('-') else c) for c in conds]]),\
f"Not all conditions are valid names. Only {possible_str} are accepted"
res = []
for cond in conds:
if cond.startswith('-'):
f = lambda: not possible_conditions[cond.replace('-', '')]()
else:
f = possible_conditions[cond]
res.append(f(commit_hash))
if args.do_and:
exit(0 if all(res) else 1)
else:
exit(0 if any(res) else 1)
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/bash
# Copyright (C) 2025 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
COMMIT_HASH=$1
python3 docs_src/build/checks.py --do-or="no_direct_edits,commit_docs_allow_direct_edits" $COMMIT_HASH ||\
(echo "Direct edits to /docs are not allowed. Please see /docs_src/README.md if you need to bypass this check." && exit 1)
+7
View File
@@ -252,6 +252,7 @@ set(MATERIAL_SRCS
src/materials/fsr/fsr_easu_mobile.mat
src/materials/fsr/fsr_easu_mobileF.mat
src/materials/fsr/fsr_rcas.mat
src/materials/sgsr/sgsr1.mat
src/materials/resolveDepth.mat
src/materials/separableGaussianBlur.mat
src/materials/skybox.mat
@@ -504,6 +505,12 @@ add_custom_command(
APPEND
)
add_custom_command(
OUTPUT "${MATERIAL_DIR}/sgsr1.filamat"
DEPENDS src/materials/sgsr/sgsr1_shader_mobile.fs
APPEND
)
add_custom_command(
OUTPUT "${MATERIAL_DIR}/separableGaussianBlur.filamat"
DEPENDS src/materials/separableGaussianBlur.vs
+1 -1
View File
@@ -139,11 +139,11 @@ if (FILAMENT_SUPPORTS_METAL)
src/metal/MetalEnums.mm
src/metal/MetalExternalImage.mm
src/metal/MetalHandles.mm
src/metal/MetalPlatform.mm
src/metal/MetalShaderCompiler.mm
src/metal/MetalState.mm
src/metal/MetalTimerQuery.mm
src/metal/MetalUtils.mm
src/metal/PlatformMetal.mm
)
set(METAL_CPP_SRCS
@@ -33,9 +33,9 @@
#include <math/vec4.h>
#include <array> // FIXME: STL headers are not allowed in public headers
#include <type_traits> // FIXME: STL headers are not allowed in public headers
#include <variant> // FIXME: STL headers are not allowed in public headers
#include <array>
#include <type_traits>
#include <variant>
#include <stddef.h>
#include <stdint.h>
+1 -1
View File
@@ -130,7 +130,7 @@ struct Handle : public HandleBase {
bool operator>=(const Handle& rhs) const noexcept { return getId() >= rhs.getId(); }
// type-safe Handle cast
template<typename B, typename = std::enable_if_t<std::is_base_of<T, B>::value> >
template<typename B, typename = std::enable_if_t<std::is_base_of_v<T, B>> >
Handle(Handle<B> const& base) noexcept : HandleBase(base) { } // NOLINT(hicpp-explicit-conversions,google-explicit-constructor)
private:
@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_METALPLATFORM_H
#define TNT_FILAMENT_BACKEND_PRIVATE_METALPLATFORM_H
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_PLATFORMMETAL_H
#define TNT_FILAMENT_BACKEND_PRIVATE_PLATFORMMETAL_H
#include <backend/DriverEnums.h>
#include <backend/Platform.h>
@@ -24,9 +24,12 @@
namespace filament::backend {
class MetalPlatform final : public Platform {
struct PlatformMetalImpl;
class PlatformMetal final : public Platform {
public:
~MetalPlatform() override;
PlatformMetal();
~PlatformMetal() noexcept override;
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
int getOSVersion() const noexcept override { return 0; }
@@ -54,11 +57,30 @@ public:
*/
id<MTLCommandBuffer> createAndEnqueueCommandBuffer() noexcept;
private:
id<MTLCommandQueue> mCommandQueue = nil;
/**
* The action to take if a Drawable cannot be acquired.
*
* Each frame rendered requires a CAMetalDrawable texture, which is presented on-screen at the
* completion of each frame. These are limited and provided round-robin style by the system.
*/
enum class DrawableFailureBehavior : uint8_t {
/**
* Terminates the application and reports an error message (default).
*/
PANIC,
/*
* Aborts execution of the current frame. The Metal backend will attempt to acquire a new
* drawable at the next frame.
*/
ABORT_FRAME
};
void setDrawableFailureBehavior(DrawableFailureBehavior behavior) noexcept;
DrawableFailureBehavior getDrawableFailureBehavior() const noexcept;
private:
PlatformMetalImpl* pImpl = nullptr;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PRIVATE_METALPLATFORM_H
#endif // TNT_FILAMENT_BACKEND_PRIVATE_PLATFORMMETAL_H
@@ -31,6 +31,7 @@
#include <cstddef>
#include <exception>
#include <mutex>
#include <type_traits>
#include <unordered_map>
#include <utility>
@@ -44,11 +45,26 @@
namespace filament::backend {
// This is used to not duplicate the code for the Tags management
class DebugTag {
public:
DebugTag();
void writeHandleTag(HandleBase::HandleId key, utils::CString&& tag) noexcept;
utils::CString findHandleTag(HandleBase::HandleId key) const noexcept;
private:
// This is used to associate a tag to a handle. mDebugTags is only written the in the main
// driver thread, but it can be accessed from any thread, because it's called from handle_cast<>
// which is used by synchronous calls.
mutable utils::Mutex mDebugTagLock;
tsl::robin_map<HandleBase::HandleId, utils::CString> mDebugTags;
};
/*
* A utility class to efficiently allocate and manage Handle<>
*/
template<size_t P0, size_t P1, size_t P2>
class HandleAllocator {
class HandleAllocator : public DebugTag {
public:
HandleAllocator(const char* name, size_t size, bool disableUseAfterFreeCheck) noexcept;
HandleAllocator(HandleAllocator const& rhs) = delete;
@@ -97,7 +113,7 @@ public:
* ConcreteTexture* p = reconstruct(h, w, h);
*/
template<typename D, typename B, typename ... ARGS>
typename std::enable_if_t<std::is_base_of_v<B, D>, D>*
std::enable_if_t<std::is_base_of_v<B, D>, D>*
destroyAndConstruct(Handle<B> const& handle, ARGS&& ... args) {
assert_invariant(handle);
D* addr = handle_cast<D*>(const_cast<Handle<B>&>(handle));
@@ -116,7 +132,7 @@ public:
* ConcreteTexture* p = construct(h, w, h);
*/
template<typename D, typename B, typename ... ARGS>
typename std::enable_if_t<std::is_base_of_v<B, D>, D>*
std::enable_if_t<std::is_base_of_v<B, D>, D>*
construct(Handle<B> const& handle, ARGS&& ... args) noexcept {
assert_invariant(handle);
D* addr = handle_cast<D*>(const_cast<Handle<B>&>(handle));
@@ -133,7 +149,7 @@ public:
* deallocate(h, p);
*/
template <typename B, typename D,
typename = typename std::enable_if_t<std::is_base_of_v<B, D>, D>>
typename = std::enable_if_t<std::is_base_of_v<B, D>, D>>
void deallocate(Handle<B>& handle, D const* p) noexcept {
// allow to destroy the nullptr, similarly to operator delete
if (p) {
@@ -161,9 +177,9 @@ public:
* ConcreteTexture* p = handle_cast<ConcreteTexture*>(h);
*/
template<typename Dp, typename B>
inline typename std::enable_if_t<
inline std::enable_if_t<
std::is_pointer_v<Dp> &&
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
std::is_base_of_v<B, std::remove_pointer_t<Dp>>, Dp>
handle_cast(Handle<B>& handle) {
assert_invariant(handle);
auto [p, tag] = handleToPointer(handle.getId());
@@ -200,6 +216,8 @@ public:
return static_cast<Dp>(p);
}
utils::CString getHandleTag(HandleBase::HandleId key) const noexcept;
template<typename B>
bool is_valid(Handle<B>& handle) {
if (!handle) {
@@ -217,9 +235,9 @@ public:
}
template<typename Dp, typename B>
inline typename std::enable_if_t<
inline std::enable_if_t<
std::is_pointer_v<Dp> &&
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
std::is_base_of_v<B, std::remove_pointer_t<Dp>>, Dp>
handle_cast(Handle<B> const& handle) {
return handle_cast<Dp>(const_cast<Handle<B>&>(handle));
}
@@ -227,24 +245,12 @@ public:
void associateTagToHandle(HandleBase::HandleId id, utils::CString&& tag) noexcept {
// TODO: for now, only pool handles check for use-after-free, so we only keep tags for
// those
if (isPoolHandle(id)) {
uint32_t key = id;
if (UTILS_LIKELY(isPoolHandle(id))) {
// Truncate the age to get the debug tag
uint32_t const key = id & ~(HANDLE_DEBUG_TAG_MASK ^ HANDLE_AGE_MASK);
// This line is the costly part. In the future, we could potentially use a custom
// allocator.
mDebugTags[key] = std::move(tag);
key &= ~(HANDLE_DEBUG_TAG_MASK ^ HANDLE_AGE_MASK);
}
}
utils::CString getHandleTag(HandleBase::HandleId id) const noexcept {
if (!isPoolHandle(id)) {
return "(no tag)";
}
uint32_t const key = id & ~(HANDLE_DEBUG_TAG_MASK ^ HANDLE_AGE_MASK);
if (auto pos = mDebugTags.find(key); pos != mDebugTags.end()) {
return pos->second;
}
return "(no tag)";
writeHandleTag(key, std::move(tag));
}
private:
@@ -347,9 +353,8 @@ private:
if (UTILS_LIKELY(p)) {
uint32_t const tag = (uint32_t(age) << HANDLE_AGE_SHIFT) & HANDLE_AGE_MASK;
return arenaPointerToHandle(p, tag);
} else {
return allocateHandleSlow(SIZE);
}
return allocateHandleSlow(SIZE);
}
template<size_t SIZE>
@@ -421,7 +426,6 @@ private:
// Below is only used when running out of space in the HandleArena
mutable utils::Mutex mLock;
tsl::robin_map<HandleBase::HandleId, void*> mOverflowMap;
tsl::robin_map<HandleBase::HandleId, utils::CString> mDebugTags;
HandleBase::HandleId mId = 0;
bool mUseAfterFreeCheckDisabled = false;
};
+39 -3
View File
@@ -19,6 +19,7 @@
#include <backend/Handle.h>
#include <utils/Allocator.h>
#include <utils/CString.h>
#include <utils/Log.h>
#include <utils/Panic.h>
#include <utils/compiler.h>
@@ -29,7 +30,9 @@
#include <exception>
#include <limits>
#include <mutex>
#include <utility>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -80,9 +83,6 @@ HandleAllocator<P0, P1, P2>::HandleAllocator(const char* name, size_t size,
bool disableUseAfterFreeCheck) noexcept
: mHandleArena(name, size, disableUseAfterFreeCheck),
mUseAfterFreeCheckDisabled(disableUseAfterFreeCheck) {
// Reserve initial space for debug tags. This prevents excessive calls to malloc when the first
// few tags are set.
mDebugTags.reserve(512);
}
template <size_t P0, size_t P1, size_t P2>
@@ -147,6 +147,42 @@ void HandleAllocator<P0, P1, P2>::deallocateHandleSlow(HandleBase::HandleId id,
::free(p);
}
template<size_t P0, size_t P1, size_t P2>
UTILS_NOINLINE
CString HandleAllocator<P0, P1, P2>::getHandleTag(HandleBase::HandleId id) const noexcept {
uint32_t key = id;
if (UTILS_LIKELY(isPoolHandle(id))) {
// Truncate the age to get the debug tag
key &= ~(HANDLE_DEBUG_TAG_MASK ^ HANDLE_AGE_MASK);
}
return findHandleTag(key);
}
DebugTag::DebugTag() {
// Reserve initial space for debug tags. This prevents excessive calls to malloc when the first
// few tags are set.
mDebugTags.reserve(512);
}
UTILS_NOINLINE
CString DebugTag::findHandleTag(HandleBase::HandleId key) const noexcept {
std::unique_lock const lock(mDebugTagLock);
if (auto pos = mDebugTags.find(key); pos != mDebugTags.end()) {
return pos->second;
}
return "(no tag)";
}
UTILS_NOINLINE
void DebugTag::writeHandleTag(HandleBase::HandleId key, CString&& tag) noexcept {
// This line is the costly part. In the future, we could potentially use a custom
// allocator.
std::unique_lock const lock(mDebugTagLock);
// Pool based tags will be recycled after a certain age. Heap-based tag will never be recycled, therefore,
// this can grow indefinitely, once we're in the slow mode.
mDebugTags[key] = std::move(tag);
}
// Explicit template instantiations.
#if defined (FILAMENT_SUPPORTS_OPENGL)
template class HandleAllocatorGL;
+5 -5
View File
@@ -18,9 +18,9 @@
#define TNT_FILAMENT_DRIVER_METALBUFFER_H
#include "MetalContext.h"
#include "MetalPlatform.h"
#include <backend/DriverEnums.h>
#include <backend/platforms/PlatformMetal.h>
#include <Metal/Metal.h>
@@ -54,12 +54,12 @@ public:
}
}
static void setPlatform(MetalPlatform* p) { platform = p; }
static void setPlatform(PlatformMetal* p) { platform = p; }
private:
typedef std::chrono::steady_clock clock_t;
static MetalPlatform* platform;
static PlatformMetal* platform;
std::chrono::time_point<clock_t> mBeginning;
const char* mName;
@@ -141,7 +141,7 @@ public:
assert_invariant(type != Type::NONE);
return aliveBuffers[toIndex(type)];
}
static void setPlatform(MetalPlatform* p) { platform = p; }
static void setPlatform(PlatformMetal* p) { platform = p; }
private:
void swap(TrackedMetalBuffer& other) noexcept {
@@ -152,7 +152,7 @@ private:
id<MTLBuffer> mBuffer;
Type mType = Type::NONE;
static MetalPlatform* platform;
static PlatformMetal* platform;
static std::array<uint64_t, TypeCount> aliveBuffers;
};
+2 -2
View File
@@ -23,8 +23,8 @@ namespace filament {
namespace backend {
std::array<uint64_t, TrackedMetalBuffer::TypeCount> TrackedMetalBuffer::aliveBuffers = { 0 };
MetalPlatform* TrackedMetalBuffer::platform = nullptr;
MetalPlatform* ScopedAllocationTimer::platform = nullptr;
PlatformMetal* TrackedMetalBuffer::platform = nullptr;
PlatformMetal* ScopedAllocationTimer::platform = nullptr;
MetalBuffer::MetalBuffer(MetalContext& context, BufferObjectBinding bindingType, BufferUsage usage,
size_t size, bool forceGpuBuffer)
@@ -128,6 +128,7 @@ struct MetalContext {
std::atomic<uint64_t> latestCompletedCommandBufferId = 0;
id<MTLCommandBuffer> pendingCommandBuffer = nil;
id<MTLRenderCommandEncoder> currentRenderPassEncoder = nil;
uint32_t currentFrame = 0;
std::atomic<bool> memorylessLimitsReached = false;
@@ -156,6 +157,7 @@ struct MetalContext {
RenderPassFlags currentRenderPassFlags;
MetalRenderTarget* currentRenderTarget = nullptr;
bool validPipelineBound = false;
bool currentRenderPassAbandoned = false;
// State trackers.
PipelineStateTracker pipelineState;
+4 -4
View File
@@ -37,7 +37,7 @@
namespace filament {
namespace backend {
class MetalPlatform;
class PlatformMetal;
class MetalBuffer;
class MetalProgram;
@@ -51,19 +51,19 @@ struct BufferState;
#endif
class MetalDriver final : public DriverBase {
explicit MetalDriver(MetalPlatform* platform, const Platform::DriverConfig& driverConfig) noexcept;
explicit MetalDriver(PlatformMetal* platform, const Platform::DriverConfig& driverConfig) noexcept;
~MetalDriver() noexcept override;
Dispatcher getDispatcher() const noexcept final;
public:
static Driver* create(MetalPlatform* platform, const Platform::DriverConfig& driverConfig);
static Driver* create(PlatformMetal* platform, const Platform::DriverConfig& driverConfig);
private:
friend class MetalSwapChain;
friend struct MetalDescriptorSet;
MetalPlatform& mPlatform;
PlatformMetal& mPlatform;
MetalContext* mContext;
ShaderModel getShaderModel() const noexcept final;
+31 -7
View File
@@ -30,7 +30,7 @@
#include "MetalState.h"
#include "MetalTimerQuery.h"
#include "MetalPlatform.h"
#include <backend/platforms/PlatformMetal.h>
#include <CoreVideo/CVMetalTexture.h>
#include <CoreVideo/CVPixelBuffer.h>
@@ -57,7 +57,7 @@
namespace filament {
namespace backend {
Driver* MetalDriverFactory::create(MetalPlatform* const platform, const Platform::DriverConfig& driverConfig) {
Driver* MetalDriverFactory::create(PlatformMetal* const platform, const Platform::DriverConfig& driverConfig) {
#if 0
// this is useful for development, but too verbose even for debug builds
// For reference on a 64-bits machine in Release mode:
@@ -96,7 +96,7 @@ Driver* MetalDriverFactory::create(MetalPlatform* const platform, const Platform
}
UTILS_NOINLINE
Driver* MetalDriver::create(MetalPlatform* const platform, const Platform::DriverConfig& driverConfig) {
Driver* MetalDriver::create(PlatformMetal* const platform, const Platform::DriverConfig& driverConfig) {
assert_invariant(platform);
size_t defaultSize = FILAMENT_METAL_HANDLE_ARENA_SIZE_IN_MB * 1024U * 1024U;
Platform::DriverConfig validConfig {driverConfig};
@@ -109,7 +109,7 @@ Dispatcher MetalDriver::getDispatcher() const noexcept {
}
MetalDriver::MetalDriver(
MetalPlatform* platform, const Platform::DriverConfig& driverConfig) noexcept
PlatformMetal* platform, const Platform::DriverConfig& driverConfig) noexcept
: mPlatform(*platform),
mContext(new MetalContext),
mHandleAllocator(
@@ -246,6 +246,7 @@ void MetalDriver::tick(int) {
void MetalDriver::beginFrame(int64_t monotonic_clock_ns,
int64_t refreshIntervalNs, uint32_t frameId) {
mContext->currentFrame = frameId;
DEBUG_LOG("beginFrame(monotonic_clock_ns = %lld, refreshIntervalNs = %lld, frameId = %d)\n",
monotonic_clock_ns, refreshIntervalNs, frameId);
#if defined(FILAMENT_METAL_PROFILING)
@@ -631,19 +632,19 @@ void MetalDriver::createFenceR(Handle<HwFence> fh, int dummy) {
void MetalDriver::createSwapChainR(Handle<HwSwapChain> sch, void* nativeWindow, uint64_t flags) {
if (UTILS_UNLIKELY(flags & SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER)) {
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef) nativeWindow;
construct_handle<MetalSwapChain>(sch, *mContext, pixelBuffer, flags);
construct_handle<MetalSwapChain>(sch, *mContext, mPlatform, pixelBuffer, flags);
// This release matches the retain call in setupExternalImage. The MetalSwapchain will have
// retained the buffer by now.
CVPixelBufferRelease((CVPixelBufferRef)pixelBuffer);
} else {
auto* metalLayer = (__bridge CAMetalLayer*) nativeWindow;
construct_handle<MetalSwapChain>(sch, *mContext, metalLayer, flags);
construct_handle<MetalSwapChain>(sch, *mContext, mPlatform, metalLayer, flags);
}
}
void MetalDriver::createSwapChainHeadlessR(Handle<HwSwapChain> sch,
uint32_t width, uint32_t height, uint64_t flags) {
construct_handle<MetalSwapChain>(sch, *mContext, width, height, flags);
construct_handle<MetalSwapChain>(sch, *mContext, mPlatform, width, height, flags);
}
void MetalDriver::createTimerQueryR(Handle<HwTimerQuery> tqh, int) {
@@ -1268,6 +1269,13 @@ void MetalDriver::beginRenderPass(Handle<HwRenderTarget> rth,
MTLRenderPassDescriptor* descriptor = [MTLRenderPassDescriptor renderPassDescriptor];
renderTarget->setUpRenderPassAttachments(descriptor, params);
if (renderTarget->involvesAbandonedSwapChain()) {
mContext->currentRenderPassAbandoned = true;
return;
} else {
mContext->currentRenderPassAbandoned = false;
}
mContext->currentRenderPassEncoder =
[getPendingCommandBuffer(mContext) renderCommandEncoderWithDescriptor:descriptor];
if (!mContext->groupMarkers.empty()) {
@@ -1329,6 +1337,10 @@ void MetalDriver::endRenderPass(int dummy) {
os_signpost_interval_end(mContext->log, OS_SIGNPOST_ID_EXCLUSIVE, "Render pass");
#endif
if (UTILS_UNLIKELY(mContext->currentRenderPassAbandoned)) {
return;
}
[mContext->currentRenderPassEncoder endEncoding];
// Command encoders are one time use. Set it to nil to release the encoder and ensure we don't
@@ -1629,6 +1641,11 @@ void MetalDriver::blitDEPRECATED(TargetBufferFlags buffers,
auto srcTarget = handle_cast<MetalRenderTarget>(src);
auto dstTarget = handle_cast<MetalRenderTarget>(dst);
if (UTILS_UNLIKELY(srcTarget->involvesAbandonedSwapChain() ||
dstTarget->involvesAbandonedSwapChain())) {
return;
}
FILAMENT_CHECK_PRECONDITION(buffers == TargetBufferFlags::COLOR0)
<< "blitDEPRECATED only supports COLOR0";
@@ -1913,6 +1930,10 @@ void MetalDriver::bindDescriptorSet(
}
void MetalDriver::draw2(uint32_t indexOffset, uint32_t indexCount, uint32_t instanceCount) {
if (UTILS_UNLIKELY(mContext->currentRenderPassAbandoned)) {
return;
}
FILAMENT_CHECK_PRECONDITION(mContext->currentRenderPassEncoder != nullptr)
<< "draw() without a valid command encoder.";
DEBUG_LOG("draw2(...)\n");
@@ -1956,6 +1977,9 @@ void MetalDriver::draw2(uint32_t indexOffset, uint32_t indexCount, uint32_t inst
void MetalDriver::draw(PipelineState ps, Handle<HwRenderPrimitive> rph,
uint32_t const indexOffset, uint32_t const indexCount, uint32_t const instanceCount) {
if (UTILS_UNLIKELY(mContext->currentRenderPassAbandoned)) {
return;
}
MetalRenderPrimitive const* const rp = handle_cast<MetalRenderPrimitive>(rph);
ps.primitiveType = rp->type;
ps.vertexBufferInfo = rp->vertexBuffer->vbih;
@@ -21,12 +21,12 @@
namespace filament {
namespace backend {
class MetalPlatform;
class PlatformMetal;
class Driver;
class MetalDriverFactory {
public:
static Driver* create(MetalPlatform* platform, const Platform::DriverConfig& driverConfig);
static Driver* create(PlatformMetal* platform, const Platform::DriverConfig& driverConfig);
};
} // namespace backend
+14 -3
View File
@@ -30,6 +30,7 @@
#include "MetalState.h" // for MetalState::VertexDescription
#include <backend/DriverEnums.h>
#include <backend/platforms/PlatformMetal.h>
#include <utils/bitset.h>
#include <utils/CString.h>
@@ -51,13 +52,16 @@ class MetalSwapChain : public HwSwapChain {
public:
// Instantiate a SwapChain from a CAMetalLayer
MetalSwapChain(MetalContext& context, CAMetalLayer* nativeWindow, uint64_t flags);
MetalSwapChain(MetalContext& context, PlatformMetal& platform, CAMetalLayer* nativeWindow,
uint64_t flags);
// Instantiate a SwapChain from a CVPixelBuffer
MetalSwapChain(MetalContext& context, CVPixelBufferRef pixelBuffer, uint64_t flags);
MetalSwapChain(MetalContext& context, PlatformMetal& platform, CVPixelBufferRef pixelBuffer,
uint64_t flags);
// Instantiate a headless SwapChain.
MetalSwapChain(MetalContext& context, int32_t width, int32_t height, uint64_t flags);
MetalSwapChain(MetalContext& context, PlatformMetal& platform, int32_t width, int32_t height,
uint64_t flags);
~MetalSwapChain();
@@ -86,6 +90,8 @@ public:
bool isPixelBuffer() const { return type == SwapChainType::CVPIXELBUFFERREF; }
bool isAbandoned() const;
private:
enum class SwapChainType {
@@ -103,6 +109,7 @@ private:
void ensureDepthStencilTexture();
MetalContext& context;
PlatformMetal& platform;
id<CAMetalDrawable> drawable = nil;
id<MTLTexture> depthStencilTexture = nil;
id<MTLTexture> headlessDrawable = nil;
@@ -114,6 +121,8 @@ private:
MetalExternalImage externalImage;
SwapChainType type;
int64_t abandonedUntilFrame = -1;
// These fields store a callback to notify the client that a frame is ready for presentation. If
// !frameScheduled.callback, then the Metal backend automatically calls presentDrawable when the
// frame is committed. Otherwise, the Metal backend will not automatically present the frame.
@@ -341,6 +350,8 @@ public:
void setUpRenderPassAttachments(MTLRenderPassDescriptor* descriptor, const RenderPassParams& params);
bool involvesAbandonedSwapChain() const noexcept;
MTLViewport getViewportFromClientViewport(
Viewport rect, float depthRangeNear, float depthRangeFar) {
const int32_t height = int32_t(getAttachmentSize().y);
+35 -4
View File
@@ -69,8 +69,10 @@ static inline MTLTextureUsage getMetalTextureUsage(TextureUsage usage) {
return MTLTextureUsage(u);
}
MetalSwapChain::MetalSwapChain(MetalContext& context, CAMetalLayer* nativeWindow, uint64_t flags)
MetalSwapChain::MetalSwapChain(
MetalContext& context, PlatformMetal& platform, CAMetalLayer* nativeWindow, uint64_t flags)
: context(context),
platform(platform),
depthStencilFormat(decideDepthStencilFormat(flags)),
layer(nativeWindow),
layerDrawableMutex(std::make_shared<std::mutex>()),
@@ -94,15 +96,19 @@ MetalSwapChain::MetalSwapChain(MetalContext& context, CAMetalLayer* nativeWindow
layer.device = context.device;
}
MetalSwapChain::MetalSwapChain(MetalContext& context, int32_t width, int32_t height, uint64_t flags)
MetalSwapChain::MetalSwapChain(MetalContext& context, PlatformMetal& platform, int32_t width,
int32_t height, uint64_t flags)
: context(context),
platform(platform),
depthStencilFormat(decideDepthStencilFormat(flags)),
headlessWidth(width),
headlessHeight(height),
type(SwapChainType::HEADLESS) {}
MetalSwapChain::MetalSwapChain(MetalContext& context, CVPixelBufferRef pixelBuffer, uint64_t flags)
MetalSwapChain::MetalSwapChain(MetalContext& context, PlatformMetal& platform,
CVPixelBufferRef pixelBuffer, uint64_t flags)
: context(context),
platform(platform),
depthStencilFormat(decideDepthStencilFormat(flags)),
externalImage(MetalExternalImage::createFromImage(context, pixelBuffer)),
type(SwapChainType::CVPIXELBUFFERREF) {
@@ -140,6 +146,10 @@ NSUInteger MetalSwapChain::getSurfaceHeight() const {
return (NSUInteger) layer.drawableSize.height;
}
bool MetalSwapChain::isAbandoned() const {
return context.currentFrame < abandonedUntilFrame;
}
id<MTLTexture> MetalSwapChain::acquireDrawable() {
if (drawable) {
return drawable.texture;
@@ -180,7 +190,18 @@ id<MTLTexture> MetalSwapChain::acquireDrawable() {
drawable = [layer nextDrawable];
}
FILAMENT_CHECK_POSTCONDITION(drawable != nil) << "Could not obtain drawable.";
if (UTILS_UNLIKELY(drawable == nil)) {
switch (platform.getDrawableFailureBehavior()) {
case PlatformMetal::DrawableFailureBehavior::PANIC:
FILAMENT_CHECK_POSTCONDITION(drawable != nil) << "Could not obtain drawable.";
break;
case PlatformMetal::DrawableFailureBehavior::ABORT_FRAME:
abandonedUntilFrame = context.currentFrame + 1;
return nil;
}
}
return drawable.texture;
}
@@ -1117,12 +1138,20 @@ void MetalRenderTarget::setUpRenderPassAttachments(MTLRenderPassDescriptor* desc
}
}
bool MetalRenderTarget::involvesAbandonedSwapChain() const noexcept {
const auto* draw = context->currentDrawSwapChain;
const auto* read = context->currentReadSwapChain;
return (draw && draw->isAbandoned()) || (read && read->isAbandoned());
}
MetalRenderTarget::Attachment MetalRenderTarget::getDrawColorAttachment(size_t index) {
assert_invariant(index < MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT);
Attachment result = color[index];
if (index == 0 && defaultRenderTarget) {
assert_invariant(context->currentDrawSwapChain);
result.texture = context->currentDrawSwapChain->acquireDrawable();
// acquireDrawable may fail to acquire the drawable, in which case result.texture will be
// nil, and an invalid attachment
}
return result;
}
@@ -1133,6 +1162,8 @@ MetalRenderTarget::Attachment MetalRenderTarget::getReadColorAttachment(size_t i
if (index == 0 && defaultRenderTarget) {
assert_invariant(context->currentReadSwapChain);
result.texture = context->currentReadSwapChain->acquireDrawable();
// acquireDrawable may fail to acquire the drawable, in which case result.texture will be
// nil, and an invalid attachment
}
return result;
}
@@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "MetalPlatform.h"
#include <backend/platforms/PlatformMetal.h>
#include "MetalDriverFactory.h"
@@ -22,19 +22,32 @@
#import <Foundation/Foundation.h>
#include <atomic>
namespace filament::backend {
struct PlatformMetalImpl {
id<MTLCommandQueue> mCommandQueue = nil;
// read form driver thread, read/written to from client thread
std::atomic<PlatformMetal::DrawableFailureBehavior> mDrawableFailureBehavior =
PlatformMetal::DrawableFailureBehavior::PANIC;
};
Platform* createDefaultMetalPlatform() {
return new MetalPlatform();
return new PlatformMetal();
}
MetalPlatform::~MetalPlatform() = default;
PlatformMetal::PlatformMetal() : pImpl(new PlatformMetalImpl) {}
Driver* MetalPlatform::createDriver(void* /*sharedContext*/, const Platform::DriverConfig& driverConfig) noexcept {
PlatformMetal::~PlatformMetal() noexcept {
delete pImpl;
}
Driver* PlatformMetal::createDriver(void* /*sharedContext*/, const Platform::DriverConfig& driverConfig) noexcept {
return MetalDriverFactory::create(this, driverConfig);
}
id<MTLDevice> MetalPlatform::createDevice() noexcept {
id<MTLDevice> PlatformMetal::createDevice() noexcept {
id<MTLDevice> result;
#if !defined(FILAMENT_IOS)
@@ -62,16 +75,24 @@ id<MTLDevice> MetalPlatform::createDevice() noexcept {
return result;
}
id<MTLCommandQueue> MetalPlatform::createCommandQueue(id<MTLDevice> device) noexcept {
mCommandQueue = [device newCommandQueue];
mCommandQueue.label = @"Filament";
return mCommandQueue;
id<MTLCommandQueue> PlatformMetal::createCommandQueue(id<MTLDevice> device) noexcept {
pImpl->mCommandQueue = [device newCommandQueue];
pImpl->mCommandQueue.label = @"Filament";
return pImpl->mCommandQueue;
}
id<MTLCommandBuffer> MetalPlatform::createAndEnqueueCommandBuffer() noexcept {
id<MTLCommandBuffer> commandBuffer = [mCommandQueue commandBuffer];
id<MTLCommandBuffer> PlatformMetal::createAndEnqueueCommandBuffer() noexcept {
id<MTLCommandBuffer> commandBuffer = [pImpl->mCommandQueue commandBuffer];
[commandBuffer enqueue];
return commandBuffer;
}
void PlatformMetal::setDrawableFailureBehavior(DrawableFailureBehavior behavior) noexcept {
pImpl->mDrawableFailureBehavior = behavior;
}
PlatformMetal::DrawableFailureBehavior PlatformMetal::getDrawableFailureBehavior() const noexcept {
return pImpl->mDrawableFailureBehavior;
}
} // namespace filament
@@ -700,6 +700,11 @@ void VulkanDriver::createFenceR(Handle<HwFence> fh, int) {
}
void VulkanDriver::createSwapChainR(Handle<HwSwapChain> sch, void* nativeWindow, uint64_t flags) {
// Running gc() to guard against an edge case where the old swapchains need to have been
// destroyed before the new swapchain can be created. Otherwise, we would fail
// vkCreateSwapchainKHR with VK_ERROR_NATIVE_WINDOW_IN_USE_KHR.
mResourceManager.gc();
if ((flags & backend::SWAP_CHAIN_CONFIG_SRGB_COLORSPACE) != 0 && !isSRGBSwapChainSupported()) {
FVK_LOGW << "sRGB swapchain requested, but Platform does not support it"
<< utils::io::endl;
@@ -296,7 +296,7 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice,
imageInfo.samples = (VkSampleCountFlagBits) samples;
VkResult result = vkCreateImage(mState->mDevice, &imageInfo, VKALLOC, &mState->mTextureImage);
if (result == VK_SUCCESS || FVK_ENABLED(FVK_DEBUG_TEXTURE)) {
if (result != VK_SUCCESS || FVK_ENABLED(FVK_DEBUG_TEXTURE)) {
FVK_LOGD << "vkCreateImage: "
<< "image = " << mState->mTextureImage << ", "
<< "result = " << result << ", "
@@ -81,7 +81,7 @@ public:
inline resource_ptr() = default;
// move constructor operator
inline resource_ptr(resource_ptr<D>&& rhs) {
inline resource_ptr(resource_ptr<D>&& rhs) noexcept {
(*this) = std::move(rhs);
}
@@ -98,7 +98,7 @@ public:
}
// move operator
inline resource_ptr<D>& operator=(resource_ptr<D> && rhs) {
inline resource_ptr<D>& operator=(resource_ptr<D> && rhs) noexcept {
std::swap(mRef, rhs.mRef);
return *this;
}
@@ -117,7 +117,7 @@ void VulkanPlatformSwapChainImpl::destroy() {
mSwapChainBundle.colors.clear();
}
VkImage VulkanPlatformSwapChainImpl::createImage(VkExtent2D extent, VkFormat format,
VkImage VulkanPlatformSwapChainImpl::createImage(VkExtent2D extent, VkFormat format,
bool isProtected) {
auto [image, memory] = createImageAndMemory(mContext, mDevice, extent, format, isProtected);
mMemory.insert({image, memory});
@@ -140,9 +140,8 @@ VulkanPlatformSurfaceSwapChain::VulkanPlatformSurfaceSwapChain(VulkanContext con
}
VulkanPlatformSurfaceSwapChain::~VulkanPlatformSurfaceSwapChain() {
vkDestroySwapchainKHR(mDevice, mSwapchain, VKALLOC);
vkDestroySurfaceKHR(mInstance, mSurface, VKALLOC);
destroy();
vkDestroySurfaceKHR(mInstance, mSurface, VKALLOC);
}
VkResult VulkanPlatformSurfaceSwapChain::create() {
@@ -256,7 +255,7 @@ VkResult VulkanPlatformSurfaceSwapChain::create() {
mSwapChainBundle.colorFormat = surfaceFormat.format;
mSwapChainBundle.depthFormat =
selectDepthFormat(mContext.getAttachmentDepthStencilFormats(), mHasStencil);
mSwapChainBundle.depth = createImage(mSwapChainBundle.extent,
mSwapChainBundle.depth = createImage(mSwapChainBundle.extent,
mSwapChainBundle.depthFormat, mIsProtected);
mSwapChainBundle.isProtected = mIsProtected;
@@ -344,6 +343,22 @@ VkResult VulkanPlatformSurfaceSwapChain::recreate() {
}
void VulkanPlatformSurfaceSwapChain::destroy() {
// The next part is not ideal. We don't have a good signal on when it's ok to destroy
// a swapchain. This is a spec oversight and mentioned as much:
// https://github.com/KhronosGroup/Vulkan-Docs/issues/1678
//
// One workaround [1] is:
// https://docs.vulkan.org/samples/latest/samples/api/swapchain_recreation/README.html
//
// The proper fix is to use VK_EXT_swapchain_maintenance1, but availability of this extension is
// unknown (not yet ratified).
//
// Instead of adding too much mechanics, we're taking a hacksaw to the problem - just wait for
// the queue to be idle. The hope is that this only happens on resize, where performance
// degradation is less obvious (until, of course, people complain about lag when rotating their
// phone). If necessary, we can revisit and implement the workaround [1].
vkQueueWaitIdle(mQueue);
VulkanPlatformSwapChainImpl::destroy();
for (uint32_t i = 0; i < IMAGE_READY_SEMAPHORE_COUNT; ++i) {
@@ -352,6 +367,10 @@ void VulkanPlatformSurfaceSwapChain::destroy() {
mImageReady[i] = VK_NULL_HANDLE;
}
}
if (mSwapchain) {
vkDestroySwapchainKHR(mDevice, mSwapchain, VKALLOC);
mSwapchain = VK_NULL_HANDLE;
}
}
VulkanPlatformHeadlessSwapChain::VulkanPlatformHeadlessSwapChain(VulkanContext const& context,
+1 -1
View File
@@ -183,7 +183,7 @@ struct UTILS_PUBLIC Aabb {
* Returns the 8 corner vertices of the AABB.
*/
Corners getCorners() const {
return Aabb::Corners{ .vertices = {
return Corners{ .vertices = {
{ min.x, min.y, min.z },
{ max.x, min.y, min.z },
{ min.x, max.y, min.z },
+2 -2
View File
@@ -73,7 +73,7 @@ public:
/**
* The binding type for this buffer object. (defaults to VERTEX)
* @param BindingType Distinguishes between SSBO, VBO, etc. For now this must be VERTEX.
* @param bindingType Distinguishes between SSBO, VBO, etc. For now this must be VERTEX.
* @return A reference to this Builder for chaining calls.
*/
Builder& bindingType(BindingType bindingType) noexcept;
@@ -91,7 +91,7 @@ public:
* @param len Length of name, should be less than or equal to 128
* @return This Builder, for chaining calls.
*/
// Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept; // inherited
Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept;
/**
* Creates the BufferObject and returns a pointer to it. After creation, the buffer
+3 -3
View File
@@ -400,14 +400,14 @@ public:
* engine.getTransformManager().getInstance(camera->getEntity()), model);
* ~~~~~~~~~~~
*
* @param model The camera position and orientation provided as a rigid transform matrix.
* @param modelMatrix The camera position and orientation provided as a rigid transform matrix.
*
* @note The Camera "looks" towards its -z axis
*
* @warning \p model must be a rigid transform
*/
void setModelMatrix(const math::mat4& model) noexcept;
void setModelMatrix(const math::mat4f& model) noexcept; //!< @overload
void setModelMatrix(const math::mat4& modelMatrix) noexcept;
void setModelMatrix(const math::mat4f& modelMatrix) noexcept; //!< @overload
/** Set the position of an eye relative to this Camera (head).
*
+3 -3
View File
@@ -194,7 +194,7 @@ inline sRGBColorA Color::toSRGB<ACCURATE>(LinearColorA const& color) {
}
inline LinearColor Color::toLinear(RgbType type, math::float3 color) {
return (type == RgbType::LINEAR) ? color : Color::toLinear<ACCURATE>(color);
return (type == RgbType::LINEAR) ? color : toLinear<ACCURATE>(color);
}
// converts an RGBA color to linear space
@@ -202,11 +202,11 @@ inline LinearColor Color::toLinear(RgbType type, math::float3 color) {
inline LinearColorA Color::toLinear(RgbaType type, math::float4 color) {
switch (type) {
case RgbaType::sRGB:
return Color::toLinear<ACCURATE>(color) * math::float4{color.a, color.a, color.a, 1.0f};
return toLinear<ACCURATE>(color) * math::float4{color.a, color.a, color.a, 1.0f};
case RgbaType::LINEAR:
return color * math::float4{color.a, color.a, color.a, 1.0f};
case RgbaType::PREMULTIPLIED_sRGB:
return Color::toLinear<ACCURATE>(color);
return toLinear<ACCURATE>(color);
case RgbaType::PREMULTIPLIED_LINEAR:
return color;
}
+21 -2
View File
@@ -537,7 +537,7 @@ public:
Platform* UTILS_NULLABLE platform = nullptr,
void* UTILS_NULLABLE sharedContext = nullptr,
const Config* UTILS_NULLABLE config = nullptr) {
return Engine::Builder()
return Builder()
.backend(backend)
.platform(platform)
.sharedContext(sharedContext)
@@ -557,7 +557,7 @@ public:
Platform* UTILS_NULLABLE platform = nullptr,
void* UTILS_NULLABLE sharedContext = nullptr,
const Config* UTILS_NULLABLE config = nullptr) {
Engine::Builder()
Builder()
.backend(backend)
.platform(platform)
.sharedContext(sharedContext)
@@ -970,6 +970,25 @@ public:
*/
void flushAndWait();
/**
* Kicks the hardware thread (e.g. the OpenGL, Vulkan or Metal thread) and blocks until
* all commands to this point are executed. Note that does guarantee that the
* hardware is actually finished.
*
* A timeout can be specified, if for some reason this flushAndWait doesn't complete before the timeout, it will
* return false, true otherwise.
*
* <p>This is typically used right after destroying the <code>SwapChain</code>,
* in cases where a guarantee about the <code>SwapChain</code> destruction is needed in a
* timely fashion, such as when responding to Android's
* <code>android.view.SurfaceHolder.Callback.surfaceDestroyed</code></p>
*
* @param timeout A timeout in nanoseconds
* @return true if successful, false if flushAndWait timed out, in which case it wasn't successful and commands
* might still be executing on both the CPU and GPU sides.
*/
bool flushAndWait(uint64_t timeout);
/**
* Kicks the hardware thread (e.g. the OpenGL, Vulkan or Metal thread) but does not wait
* for commands to be either executed or the hardware finished.
+1 -1
View File
@@ -96,7 +96,7 @@ public:
* @param len Length of name, should be less than or equal to 128
* @return This Builder, for chaining calls.
*/
// Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept; // inherited
Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept;
/**
* Creates the IndexBuffer object and returns a pointer to it. After creation, the index
+1 -1
View File
@@ -83,7 +83,7 @@ public:
* @param len Length of name, should be less than or equal to 128
* @return This Builder, for chaining calls.
*/
// Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept; // inherited
Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept;
/**
* Creates the InstanceBuffer object and returns a pointer to it.
+5 -5
View File
@@ -118,10 +118,10 @@ public:
Builder& package(const void* UTILS_NONNULL payload, size_t size);
template<typename T>
using is_supported_constant_parameter_t = typename std::enable_if<
std::is_same<int32_t, T>::value ||
std::is_same<float, T>::value ||
std::is_same<bool, T>::value>::type;
using is_supported_constant_parameter_t = std::enable_if_t<
std::is_same_v<int32_t, T> ||
std::is_same_v<float, T> ||
std::is_same_v<bool, T>>;
/**
* Specialize a constant parameter specified in the material definition with a concrete
@@ -177,7 +177,7 @@ public:
* memory or other resources.
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
*/
Material* UTILS_NULLABLE build(Engine& engine);
Material* UTILS_NULLABLE build(Engine& engine) const;
private:
friend class FMaterial;
};
+41 -41
View File
@@ -56,35 +56,35 @@ class UTILS_PUBLIC MaterialInstance : public FilamentAPI {
};
public:
using CullingMode = filament::backend::CullingMode;
using TransparencyMode = filament::TransparencyMode;
using DepthFunc = filament::backend::SamplerCompareFunc;
using StencilCompareFunc = filament::backend::SamplerCompareFunc;
using StencilOperation = filament::backend::StencilOperation;
using StencilFace = filament::backend::StencilFace;
using CullingMode = backend::CullingMode;
using TransparencyMode = TransparencyMode;
using DepthFunc = backend::SamplerCompareFunc;
using StencilCompareFunc = backend::SamplerCompareFunc;
using StencilOperation = backend::StencilOperation;
using StencilFace = backend::StencilFace;
template<typename T>
using is_supported_parameter_t = typename std::enable_if<
std::is_same<float, T>::value ||
std::is_same<int32_t, T>::value ||
std::is_same<uint32_t, T>::value ||
std::is_same<math::int2, T>::value ||
std::is_same<math::int3, T>::value ||
std::is_same<math::int4, T>::value ||
std::is_same<math::uint2, T>::value ||
std::is_same<math::uint3, T>::value ||
std::is_same<math::uint4, T>::value ||
std::is_same<math::float2, T>::value ||
std::is_same<math::float3, T>::value ||
std::is_same<math::float4, T>::value ||
std::is_same<math::mat4f, T>::value ||
using is_supported_parameter_t = std::enable_if_t<
std::is_same_v<float, T> ||
std::is_same_v<int32_t, T> ||
std::is_same_v<uint32_t, T> ||
std::is_same_v<math::int2, T> ||
std::is_same_v<math::int3, T> ||
std::is_same_v<math::int4, T> ||
std::is_same_v<math::uint2, T> ||
std::is_same_v<math::uint3, T> ||
std::is_same_v<math::uint4, T> ||
std::is_same_v<math::float2, T> ||
std::is_same_v<math::float3, T> ||
std::is_same_v<math::float4, T> ||
std::is_same_v<math::mat4f, T> ||
// these types are slower as they need a layout conversion
std::is_same<bool, T>::value ||
std::is_same<math::bool2, T>::value ||
std::is_same<math::bool3, T>::value ||
std::is_same<math::bool4, T>::value ||
std::is_same<math::mat3f, T>::value
>::type;
std::is_same_v<bool, T> ||
std::is_same_v<math::bool2, T> ||
std::is_same_v<math::bool3, T> ||
std::is_same_v<math::bool4, T> ||
std::is_same_v<math::mat3f, T>
>;
/**
* Creates a new MaterialInstance using another MaterialInstance as a template for initialization.
@@ -121,13 +121,13 @@ public:
/** inline helper to provide the name as a null-terminated string literal */
template<typename T, typename = is_supported_parameter_t<T>>
inline void setParameter(StringLiteral name, T const& value) {
void setParameter(StringLiteral name, T const& value) {
setParameter<T>(name.data, name.size, value);
}
/** inline helper to provide the name as a null-terminated C string */
template<typename T, typename = is_supported_parameter_t<T>>
inline void setParameter(const char* UTILS_NONNULL name, T const& value) {
void setParameter(const char* UTILS_NONNULL name, T const& value) {
setParameter<T>(name, strlen(name), value);
}
@@ -148,14 +148,14 @@ public:
/** inline helper to provide the name as a null-terminated string literal */
template<typename T, typename = is_supported_parameter_t<T>>
inline void setParameter(StringLiteral name, const T* UTILS_NONNULL values, size_t count) {
void setParameter(StringLiteral name, const T* UTILS_NONNULL values, size_t count) {
setParameter<T>(name.data, name.size, values, count);
}
/** inline helper to provide the name as a null-terminated C string */
template<typename T, typename = is_supported_parameter_t<T>>
inline void setParameter(const char* UTILS_NONNULL name,
const T* UTILS_NONNULL values, size_t count) {
void setParameter(const char* UTILS_NONNULL name,
const T* UTILS_NONNULL values, size_t count) {
setParameter<T>(name, strlen(name), values, count);
}
@@ -176,14 +176,14 @@ public:
Texture const* UTILS_NULLABLE texture, TextureSampler const& sampler);
/** inline helper to provide the name as a null-terminated string literal */
inline void setParameter(StringLiteral name,
Texture const* UTILS_NULLABLE texture, TextureSampler const& sampler) {
void setParameter(StringLiteral name,
Texture const* UTILS_NULLABLE texture, TextureSampler const& sampler) {
setParameter(name.data, name.size, texture, sampler);
}
/** inline helper to provide the name as a null-terminated C string */
inline void setParameter(const char* UTILS_NONNULL name,
Texture const* UTILS_NULLABLE texture, TextureSampler const& sampler) {
void setParameter(const char* UTILS_NONNULL name,
Texture const* UTILS_NULLABLE texture, TextureSampler const& sampler) {
setParameter(name, strlen(name), texture, sampler);
}
@@ -202,12 +202,12 @@ public:
RgbType type, math::float3 color);
/** inline helper to provide the name as a null-terminated string literal */
inline void setParameter(StringLiteral name, RgbType type, math::float3 color) {
void setParameter(StringLiteral name, RgbType type, math::float3 color) {
setParameter(name.data, name.size, type, color);
}
/** inline helper to provide the name as a null-terminated C string */
inline void setParameter(const char* UTILS_NONNULL name, RgbType type, math::float3 color) {
void setParameter(const char* UTILS_NONNULL name, RgbType type, math::float3 color) {
setParameter(name, strlen(name), type, color);
}
@@ -226,12 +226,12 @@ public:
RgbaType type, math::float4 color);
/** inline helper to provide the name as a null-terminated string literal */
inline void setParameter(StringLiteral name, RgbaType type, math::float4 color) {
void setParameter(StringLiteral name, RgbaType type, math::float4 color) {
setParameter(name.data, name.size, type, color);
}
/** inline helper to provide the name as a null-terminated C string */
inline void setParameter(const char* UTILS_NONNULL name, RgbaType type, math::float4 color) {
void setParameter(const char* UTILS_NONNULL name, RgbaType type, math::float4 color) {
setParameter(name, strlen(name), type, color);
}
@@ -251,13 +251,13 @@ public:
/** inline helper to provide the name as a null-terminated C string */
template<typename T, typename = is_supported_parameter_t<T>>
inline T getParameter(StringLiteral name) const {
T getParameter(StringLiteral name) const {
return getParameter<T>(name.data, name.size);
}
/** inline helper to provide the name as a null-terminated C string */
template<typename T, typename = is_supported_parameter_t<T>>
inline T getParameter(const char* UTILS_NONNULL name) const {
T getParameter(const char* UTILS_NONNULL name) const {
return getParameter<T>(name, strlen(name));
}
@@ -76,7 +76,7 @@ public:
* @param len Length of name, should be less than or equal to 128
* @return This Builder, for chaining calls.
*/
// Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept; // inherited
Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept;
/**
* Creates the MorphTargetBuffer object and returns a pointer to it.
+2 -2
View File
@@ -86,10 +86,10 @@ struct DynamicResolutionOptions {
/**
* Upscaling quality
* LOW: bilinear filtered blit. Fastest, poor quality
* MEDIUM: AMD FidelityFX FSR1 w/ mobile optimizations
* MEDIUM: Qualcomm Snapdragon Game Super Resolution (SGSR) 1.0
* HIGH: AMD FidelityFX FSR1 w/ mobile optimizations
* ULTRA: AMD FidelityFX FSR1
* FSR1 require a well anti-aliased (MSAA or TAA), noise free scene.
* FSR1 and SGSR require a well anti-aliased (MSAA or TAA), noise free scene. Avoid FXAA and dithering.
*
* The default upscaling quality is set to LOW.
*/
+20 -13
View File
@@ -220,7 +220,7 @@ public:
* the renderable are immutable.
* STATIC geometry has the same restrictions as STATIC_BOUNDS, but in addition disallows
* skinning, morphing and changing the VertexBuffer or IndexBuffer in any way.
* @param enable whether this renderable has static bounds. false by default.
* @param type type of geometry.
*/
Builder& geometryType(GeometryType type) noexcept;
@@ -454,7 +454,7 @@ public:
*
* @param primitiveIndex zero-based index of the primitive, must be less than the primitive
* count passed to Builder constructor
* @param indicesAndWeightsVectors pairs of bone index and bone weight for all vertices of
* @param indicesAndWeightsVector pairs of bone index and bone weight for all vertices of
* the primitive sequentially
*
* @return Builder reference for chaining calls.
@@ -501,7 +501,7 @@ public:
* @param primitiveIndex zero-based index of the primitive, must be less than the count passed to Builder constructor
* @param offset specifies where in the morph target buffer to start reading (expressed as a number of vertices)
*/
RenderableManager::Builder& morphing(uint8_t level,
Builder& morphing(uint8_t level,
size_t primitiveIndex, size_t offset) noexcept;
@@ -798,6 +798,13 @@ public:
void setMaterialInstanceAt(Instance instance,
size_t primitiveIndex, MaterialInstance const* UTILS_NONNULL materialInstance);
/**
* Clear the MaterialInstance for the given primitive.
* @param instance Renderable's instance
* @param primitiveIndex Primitive index
*/
void clearMaterialInstanceAt(Instance instance, size_t primitiveIndex);
/**
* Retrieves the material instance that is bound to the given primitive.
*/
@@ -845,20 +852,20 @@ public:
/*! \cond PRIVATE */
template<typename T>
struct is_supported_vector_type {
using type = typename std::enable_if<
std::is_same<math::float4, T>::value ||
std::is_same<math::half4, T>::value ||
std::is_same<math::float3, T>::value ||
std::is_same<math::half3, T>::value
>::type;
using type = std::enable_if_t<
std::is_same_v<math::float4, T> ||
std::is_same_v<math::half4, T> ||
std::is_same_v<math::float3, T> ||
std::is_same_v<math::half3, T>
>;
};
template<typename T>
struct is_supported_index_type {
using type = typename std::enable_if<
std::is_same<uint16_t, T>::value ||
std::is_same<uint32_t, T>::value
>::type;
using type = std::enable_if_t<
std::is_same_v<uint16_t, T> ||
std::is_same_v<uint32_t, T>
>;
};
/*! \endcond */
+1 -1
View File
@@ -105,7 +105,7 @@ public:
* @param historySize requested history size. The returned vector could be smaller.
* @return A vector of FrameInfo.
*/
utils::FixedCapacityVector<Renderer::FrameInfo> getFrameInfoHistory(
utils::FixedCapacityVector<FrameInfo> getFrameInfoHistory(
size_t historySize = 1) const noexcept;
/**
+1 -1
View File
@@ -82,7 +82,7 @@ public:
* @param len Length of name, should be less than or equal to 128
* @return This Builder, for chaining calls.
*/
// Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept; // inherited
Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept;
/**
* Creates the SkinningBuffer object and returns a pointer to it.
+1 -1
View File
@@ -149,7 +149,7 @@ public:
* @param len Length of name, should be less than or equal to 128
* @return This Builder, for chaining calls.
*/
// Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept; // inherited
Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept;
/**
* Creates the Stream object and returns a pointer to it.
+2 -2
View File
@@ -94,7 +94,7 @@ public:
/** @return whether a backend supports texture swizzling. */
static bool isTextureSwizzleSupported(Engine& engine) noexcept;
static size_t computeTextureDataSize(Texture::Format format, Texture::Type type,
static size_t computeTextureDataSize(Format format, Type type,
size_t stride, size_t height, size_t alignment) noexcept;
@@ -215,7 +215,7 @@ public:
* @param len Length of name, should be less than or equal to 128
* @return This Builder, for chaining calls.
*/
// Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept; // inherited
Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept;
/**
* Creates the Texture object and returns a pointer to it.
+1 -1
View File
@@ -171,7 +171,7 @@ public:
* @param len Length of name, should be less than or equal to 128
* @return This Builder, for chaining calls.
*/
// Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept; // inherited
Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept;
/**
* Creates the VertexBuffer object and returns a pointer to it.
+9 -9
View File
@@ -22,7 +22,7 @@ namespace filament {
using namespace utils;
static inline constexpr std::pair<uint8_t, uint8_t> unmorton(uint16_t m) noexcept {
static inline constexpr std::pair<uint8_t, uint8_t> unmorton(uint16_t const m) noexcept {
uint32_t r = (m | (uint32_t(m) << 15u)) & 0x55555555u;
r = (r | (r >> 1u)) & 0x33333333u;
r = (r | (r >> 2u)) & 0x0f0f0f0fu;
@@ -30,14 +30,14 @@ static inline constexpr std::pair<uint8_t, uint8_t> unmorton(uint16_t m) noexcep
return { uint8_t(r), uint8_t(r >> 16u) };
}
AtlasAllocator::AtlasAllocator(size_t maxTextureSize) noexcept {
AtlasAllocator::AtlasAllocator(size_t const maxTextureSize) noexcept {
// round to power-of-two immediately inferior or equal to the size specified.
mMaxTextureSizePot = (sizeof(maxTextureSize) * 8 - 1u) - utils::clz(maxTextureSize);
mMaxTextureSizePot = (sizeof(maxTextureSize) * 8 - 1u) - clz(maxTextureSize);
}
AtlasAllocator::Allocation AtlasAllocator::allocate(size_t textureSize) noexcept {
AtlasAllocator::Allocation AtlasAllocator::allocate(size_t const textureSize) noexcept {
Allocation result{};
const size_t powerOfTwo = (sizeof(textureSize) * 8 - 1u) - utils::clz(textureSize);
const size_t powerOfTwo = (sizeof(textureSize) * 8 - 1u) - clz(textureSize);
// asked for a texture size too large
if (UTILS_UNLIKELY(powerOfTwo > mMaxTextureSizePot)) {
@@ -67,12 +67,12 @@ AtlasAllocator::Allocation AtlasAllocator::allocate(size_t textureSize) noexcept
return result;
}
void AtlasAllocator::clear(size_t maxTextureSize) noexcept {
void AtlasAllocator::clear(size_t const maxTextureSize) noexcept {
std::fill(mQuadTree.begin(), mQuadTree.end(), Node{});
mMaxTextureSizePot = (sizeof(maxTextureSize) * 8 - 1u) - utils::clz(maxTextureSize);
mMaxTextureSizePot = (sizeof(maxTextureSize) * 8 - 1u) - clz(maxTextureSize);
}
AtlasAllocator::NodeId AtlasAllocator::allocateInLayer(size_t maxHeight) noexcept {
AtlasAllocator::NodeId AtlasAllocator::allocateInLayer(size_t const maxHeight) noexcept {
using namespace QuadTreeUtils;
NodeId candidate{ -1, 0 };
@@ -155,7 +155,7 @@ AtlasAllocator::NodeId AtlasAllocator::allocateInLayer(size_t maxHeight) noexcep
if (candidate.l > 0) {
// first thing to do is to update our parent's children count (the first node
// doesn't have a parent).
size_t const pi = QuadTreeUtils::parent(candidate.l, candidate.code);
size_t const pi = parent(candidate.l, candidate.code);
Node& parentNode = mQuadTree[pi];
assert_invariant(!parentNode.isAllocated());
assert_invariant(!parentNode.hasAllChildren());
+1 -1
View File
@@ -23,7 +23,7 @@
namespace filament {
void BufferObject::setBuffer(Engine& engine,
BufferObject::BufferDescriptor&& buffer, uint32_t byteOffset) {
BufferDescriptor&& buffer, uint32_t const byteOffset) {
downcast(this)->setBuffer(downcast(engine), std::move(buffer), byteOffset);
}
+1 -1
View File
@@ -103,7 +103,7 @@ void BufferPoolAllocator<POOL_SIZE, ALIGNMENT, AllocatorPolicy, LockingPolicy>::
}
template<size_t POOL_SIZE, size_t ALIGNMENT, typename AllocatorPolicy, typename LockingPolicy>
void* BufferPoolAllocator<POOL_SIZE, ALIGNMENT, AllocatorPolicy, LockingPolicy>::get(size_type size) noexcept {
void* BufferPoolAllocator<POOL_SIZE, ALIGNMENT, AllocatorPolicy, LockingPolicy>::get(size_type const size) noexcept {
std::lock_guard<LockingPolicy> guard(mLock);
// if the requested size is larger that our buffers in the pool, we just empty the pool
+23 -23
View File
@@ -22,16 +22,16 @@ namespace filament {
using namespace math;
void Camera::setProjection(double fovInDegrees, double aspect, double near, double far,
Camera::Fov direction) {
void Camera::setProjection(double const fovInDegrees, double const aspect, double const near, double const far,
Fov const direction) {
setCustomProjection(
projection(direction, fovInDegrees, aspect, near),
projection(direction, fovInDegrees, aspect, near, far),
near, far);
}
void Camera::setLensProjection(double focalLengthInMillimeters,
double aspect, double near, double far) {
void Camera::setLensProjection(double const focalLengthInMillimeters,
double const aspect, double const near, double const far) {
setCustomProjection(
projection(focalLengthInMillimeters, aspect, near),
projection(focalLengthInMillimeters, aspect, near, far),
@@ -46,38 +46,38 @@ mat4 Camera::inverseProjection(const mat4& p) noexcept {
return inverse(p);
}
void Camera::setEyeModelMatrix(uint8_t eyeId, math::mat4 const& model) {
void Camera::setEyeModelMatrix(uint8_t const eyeId, mat4 const& model) {
downcast(this)->setEyeModelMatrix(eyeId, model);
}
void Camera::setCustomEyeProjection(math::mat4 const* projection, size_t count,
math::mat4 const& projectionForCulling, double near, double far) {
void Camera::setCustomEyeProjection(mat4 const* projection, size_t const count,
mat4 const& projectionForCulling, double const near, double const far) {
downcast(this)->setCustomEyeProjection(projection, count, projectionForCulling, near, far);
}
void Camera::setProjection(Camera::Projection projection, double left, double right, double bottom,
double top, double near, double far) {
void Camera::setProjection(Projection const projection, double const left, double const right, double const bottom,
double const top, double const near, double const far) {
downcast(this)->setProjection(projection, left, right, bottom, top, near, far);
}
void Camera::setCustomProjection(mat4 const& projection, double near, double far) noexcept {
void Camera::setCustomProjection(mat4 const& projection, double const near, double const far) noexcept {
downcast(this)->setCustomProjection(projection, near, far);
}
void Camera::setCustomProjection(mat4 const& projection, mat4 const& projectionForCulling,
double near, double far) noexcept {
double const near, double const far) noexcept {
downcast(this)->setCustomProjection(projection, projectionForCulling, near, far);
}
void Camera::setScaling(double2 scaling) noexcept {
void Camera::setScaling(double2 const scaling) noexcept {
downcast(this)->setScaling(scaling);
}
void Camera::setShift(double2 shift) noexcept {
void Camera::setShift(double2 const shift) noexcept {
downcast(this)->setShift(shift);
}
mat4 Camera::getProjectionMatrix(uint8_t eyeId) const {
mat4 Camera::getProjectionMatrix(uint8_t const eyeId) const {
return downcast(this)->getUserProjectionMatrix(eyeId);
}
@@ -137,7 +137,7 @@ float3 Camera::getForwardVector() const noexcept {
return downcast(this)->getForwardVector();
}
float Camera::getFieldOfViewInDegrees(Camera::Fov direction) const noexcept {
float Camera::getFieldOfViewInDegrees(Fov const direction) const noexcept {
return downcast(this)->getFieldOfViewInDegrees(direction);
}
@@ -149,7 +149,7 @@ utils::Entity Camera::getEntity() const noexcept {
return downcast(this)->getEntity();
}
void Camera::setExposure(float aperture, float shutterSpeed, float ISO) noexcept {
void Camera::setExposure(float const aperture, float const shutterSpeed, float const ISO) noexcept {
downcast(this)->setExposure(aperture, shutterSpeed, ISO);
}
@@ -165,7 +165,7 @@ float Camera::getSensitivity() const noexcept {
return downcast(this)->getSensitivity();
}
void Camera::setFocusDistance(float distance) noexcept {
void Camera::setFocusDistance(float const distance) noexcept {
downcast(this)->setFocusDistance(distance);
}
@@ -177,21 +177,21 @@ double Camera::getFocalLength() const noexcept {
return downcast(this)->getFocalLength();
}
double Camera::computeEffectiveFocalLength(double focalLength, double focusDistance) noexcept {
double Camera::computeEffectiveFocalLength(double const focalLength, double const focusDistance) noexcept {
return FCamera::computeEffectiveFocalLength(focalLength, focusDistance);
}
double Camera::computeEffectiveFov(double fovInDegrees, double focusDistance) noexcept {
double Camera::computeEffectiveFov(double const fovInDegrees, double const focusDistance) noexcept {
return FCamera::computeEffectiveFov(fovInDegrees, focusDistance);
}
math::mat4 Camera::projection(Fov direction, double fovInDegrees,
double aspect, double near, double far) {
mat4 Camera::projection(Fov const direction, double const fovInDegrees,
double const aspect, double const near, double const far) {
return FCamera::projection(direction, fovInDegrees, aspect, near, far);
}
math::mat4 Camera::projection(double focalLengthInMillimeters,
double aspect, double near, double far) {
mat4 Camera::projection(double const focalLengthInMillimeters,
double const aspect, double const near, double const far) {
return FCamera::projection(focalLengthInMillimeters, aspect, near, far);
}
+5 -5
View File
@@ -25,15 +25,15 @@ namespace filament {
using namespace math;
float3 Color::sRGBToLinear(float3 color) noexcept {
float3 Color::sRGBToLinear(float3 const color) noexcept {
return EOTF_sRGB(color);
}
float3 Color::linearToSRGB(float3 color) noexcept {
float3 Color::linearToSRGB(float3 const color) noexcept {
return OETF_sRGB(color);
}
LinearColor Color::cct(float K) {
LinearColor Color::cct(float const K) {
// temperature to CIE 1960
float const K2 = K * K;
float const u = (0.860117757f + 1.54118254e-4f * K + 1.28641212e-7f * K2) /
@@ -47,7 +47,7 @@ LinearColor Color::cct(float K) {
return saturate(linear / max(1e-5f, max(linear)));
}
LinearColor Color::illuminantD(float K) {
LinearColor Color::illuminantD(float const K) {
// temperature to xyY
const float iK = 1.0f / K;
float const iK2 = iK * iK;
@@ -61,7 +61,7 @@ LinearColor Color::illuminantD(float K) {
return saturate(linear / max(1e-5f, max(linear)));
}
LinearColor Color::absorptionAtDistance(LinearColor const& color, float distance) {
LinearColor Color::absorptionAtDistance(LinearColor const& color, float const distance) {
return -log(clamp(color, 1e-5f, 1.0f)) / max(1e-5f, distance);
}
+5 -5
View File
@@ -52,7 +52,7 @@ using namespace math;
// Finds the maximum saturation possible for a given hue that fits in sRGB
// Saturation here is defined as S = C/L
// a and b must be normalized so a^2 + b^2 == 1
static float compute_max_saturation(float a, float b) noexcept {
static float compute_max_saturation(float const a, float const b) noexcept {
// Max saturation will be when one of r, g or b goes below zero.
// Select different coefficients depending on which component goes below zero first
@@ -131,7 +131,7 @@ static float compute_max_saturation(float a, float b) noexcept {
// finds L_cusp and C_cusp for a given hue
// a and b must be normalized so a^2 + b^2 == 1
static float2 find_cusp(float a, float b) noexcept {
static float2 find_cusp(float const a, float const b) noexcept {
// First, find the maximum saturation (saturation S = C/L)
float const S_cusp = compute_max_saturation(a, b);
@@ -147,7 +147,7 @@ static float2 find_cusp(float a, float b) noexcept {
// L = L0 * (1 - t) + t * L1;
// C = t * C1;
// a and b must be normalized so a^2 + b^2 == 1
static float find_gamut_intersection(float a, float b, float L1, float C1, float L0) noexcept {
static float find_gamut_intersection(float const a, float const b, float const L1, float const C1, float const L0) noexcept {
// Find the cusp of the gamut triangle
float2 const cusp = find_cusp(a, b);
@@ -231,7 +231,7 @@ static float find_gamut_intersection(float a, float b, float L1, float C1, float
return t;
}
constexpr float sgn(float x) noexcept {
constexpr float sgn(float const x) noexcept {
return (float) (0.f < x) - (float) (x < 0.f);
}
@@ -266,7 +266,7 @@ inline float3 gamut_clip_adaptive_L0_0_5(float3 rgb,
return OkLab_to_sRGB({L_clipped, C_clipped * a_, C_clipped * b_});
}
float3 gamutMapping_sRGB(float3 rgb) noexcept {
float3 gamutMapping_sRGB(float3 const rgb) noexcept {
return gamut_clip_adaptive_L0_0_5(rgb);
}
+10 -10
View File
@@ -213,7 +213,7 @@ constexpr float MIDDLE_GRAY_ACEScct = 0.4135884f;
// Returns the y chromaticity coordinate in xyY for an illuminant series D,
// given its x chromaticity coordinate.
inline constexpr float chromaticityCoordinateIlluminantD(float x) noexcept {
inline constexpr float chromaticityCoordinateIlluminantD(float const x) noexcept {
// See http://en.wikipedia.org/wiki/Standard_illuminant#Illuminant_series_D
return 2.87f * x - 3.0f * x * x - 0.275f;
}
@@ -222,7 +222,7 @@ inline constexpr float chromaticityCoordinateIlluminantD(float x) noexcept {
// Color space conversions
//------------------------------------------------------------------------------
inline constexpr XYZ xyY_to_XYZ(xyY v) noexcept {
inline constexpr XYZ xyY_to_XYZ(xyY const v) noexcept {
const float a = v.z / max(v.y, 1e-5f);
return XYZ{v.x * a, v.z, (1.0f - v.x - v.y) * a};
}
@@ -231,23 +231,23 @@ inline constexpr xyY XYZ_to_xyY(XYZ v) noexcept {
return {v.xy / max(v.x + v.y + v.z, 1e-5f), v.y};
}
inline constexpr float3 pow3(float3 x) noexcept {
inline constexpr float3 pow3(float3 const x) noexcept {
return x * x * x;
}
inline float3 sRGB_to_OkLab(float3 x) noexcept {
inline float3 sRGB_to_OkLab(float3 const x) noexcept {
return OkLab_LMS_to_OkLab * cbrt(sRGB_to_OkLab_LMS * x);
}
inline float3 Rec2020_to_OkLab(float3 x) noexcept {
inline float3 Rec2020_to_OkLab(float3 const x) noexcept {
return OkLab_LMS_to_OkLab * cbrt(Rec2020_to_OkLab_LMS * x);
}
inline float3 OkLab_to_sRGB(float3 x) noexcept {
inline float3 OkLab_to_sRGB(float3 const x) noexcept {
return OkLab_LMS_to_sRGB * pow3(OkLab_to_OkLab_LMS * x);
}
inline float3 OkLab_to_Rec2020(float3 x) noexcept {
inline float3 OkLab_to_Rec2020(float3 const x) noexcept {
return OkLab_LMS_to_Rec2020 * pow3(OkLab_to_OkLab_LMS * x);
}
@@ -256,7 +256,7 @@ inline float3 OkLab_to_Rec2020(float3 x) noexcept {
//------------------------------------------------------------------------------
// Decodes a linear value from LogC using the Alexa LogC EI 1000 curve
inline float3 LogC_to_linear(float3 x) noexcept {
inline float3 LogC_to_linear(float3 const x) noexcept {
const float ia = 1.0f / 5.555556f;
const float b = 0.047996f;
const float ic = 1.0f / 0.244161f;
@@ -265,7 +265,7 @@ inline float3 LogC_to_linear(float3 x) noexcept {
}
// Encodes a linear value in LogC using the Alexa LogC EI 1000 curve
inline float3 linear_to_LogC(float3 x) noexcept {
inline float3 linear_to_LogC(float3 const x) noexcept {
const float a = 5.555556f;
const float b = 0.047996f;
const float c = 0.244161f;
@@ -296,7 +296,7 @@ inline float3 linearAP1_to_ACEScct(float3 x) noexcept {
return x;
}
inline float3 OETF_Linear(float3 x) noexcept {
inline float3 OETF_Linear(float3 const x) noexcept {
return x;
}
+7 -7
View File
@@ -64,7 +64,7 @@ void Culler::intersects(
Frustum const& UTILS_RESTRICT frustum,
float3 const* UTILS_RESTRICT center,
float3 const* UTILS_RESTRICT extent,
size_t count, size_t bit) noexcept {
size_t count, size_t const bit) noexcept {
float4 const * UTILS_RESTRICT const planes = frustum.mPlanes;
@@ -101,10 +101,10 @@ bool Culler::intersects(Frustum const& frustum, Box const& box) noexcept {
// The main intersection routine assumes multiples of 8 items
float3 centers[MODULO];
float3 extents[MODULO];
Culler::result_type results[MODULO];
result_type results[MODULO];
centers[0] = box.center;
extents[0] = box.halfExtent;
Culler::intersects(results, frustum, centers, extents, MODULO, 0);
intersects(results, frustum, centers, extents, MODULO, 0);
return bool(results[0] & 1);
}
@@ -114,9 +114,9 @@ bool Culler::intersects(Frustum const& frustum, Box const& box) noexcept {
bool Culler::intersects(Frustum const& frustum, float4 const& sphere) noexcept {
// The main intersection routine assumes multiples of 8 items
float4 spheres[MODULO];
Culler::result_type results[MODULO];
result_type results[MODULO];
spheres[0] = sphere;
Culler::intersects(results, frustum, spheres, MODULO);
intersects(results, frustum, spheres, MODULO);
return bool(results[0] & 1);
}
@@ -127,14 +127,14 @@ void Culler::Test::intersects(
Frustum const& UTILS_RESTRICT frustum,
float3 const* UTILS_RESTRICT c,
float3 const* UTILS_RESTRICT e,
size_t count) noexcept {
size_t const count) noexcept {
Culler::intersects(results, frustum, c, e, count, 0);
}
void Culler::Test::intersects(
result_type* UTILS_RESTRICT results,
Frustum const& UTILS_RESTRICT frustum,
float4 const* UTILS_RESTRICT b, size_t count) noexcept {
float4 const* UTILS_RESTRICT b, size_t const count) noexcept {
Culler::intersects(results, frustum, b, count);
}
+1 -1
View File
@@ -38,7 +38,7 @@ class Culler {
public:
// Culler can only process buffers with a size multiple of MODULO
static constexpr size_t MODULO = 8u;
static inline size_t round(size_t count) noexcept {
static inline size_t round(size_t const count) noexcept {
return (count + (MODULO - 1)) & ~(MODULO - 1);
}
+6 -6
View File
@@ -28,27 +28,27 @@ bool DebugRegistry::hasProperty(const char* name) const noexcept {
return downcast(this)->hasProperty(name);
}
bool DebugRegistry::setProperty(const char* name, bool v) noexcept {
bool DebugRegistry::setProperty(const char* name, bool const v) noexcept {
return downcast(this)->setProperty(name, v);
}
bool DebugRegistry::setProperty(const char* name, int v) noexcept {
bool DebugRegistry::setProperty(const char* name, int const v) noexcept {
return downcast(this)->setProperty(name, v);
}
bool DebugRegistry::setProperty(const char* name, float v) noexcept {
bool DebugRegistry::setProperty(const char* name, float const v) noexcept {
return downcast(this)->setProperty(name, v);
}
bool DebugRegistry::setProperty(const char* name, float2 v) noexcept {
bool DebugRegistry::setProperty(const char* name, float2 const v) noexcept {
return downcast(this)->setProperty(name, v);
}
bool DebugRegistry::setProperty(const char* name, float3 v) noexcept {
bool DebugRegistry::setProperty(const char* name, float3 const v) noexcept {
return downcast(this)->setProperty(name, v);
}
bool DebugRegistry::setProperty(const char* name, float4 v) noexcept {
bool DebugRegistry::setProperty(const char* name, float4 const v) noexcept {
return downcast(this)->setProperty(name, v);
}
+18 -14
View File
@@ -104,15 +104,15 @@ Scene* Engine::createScene() noexcept {
return downcast(this)->createScene();
}
Camera* Engine::createCamera(Entity entity) noexcept {
Camera* Engine::createCamera(Entity const entity) noexcept {
return downcast(this)->createCamera(entity);
}
Camera* Engine::getCameraComponent(utils::Entity entity) noexcept {
Camera* Engine::getCameraComponent(Entity const entity) noexcept {
return downcast(this)->getCameraComponent(entity);
}
void Engine::destroyCameraComponent(utils::Entity entity) noexcept {
void Engine::destroyCameraComponent(Entity const entity) noexcept {
downcast(this)->destroyCameraComponent(entity);
}
@@ -120,11 +120,11 @@ Fence* Engine::createFence() noexcept {
return downcast(this)->createFence();
}
SwapChain* Engine::createSwapChain(void* nativeWindow, uint64_t flags) noexcept {
SwapChain* Engine::createSwapChain(void* nativeWindow, uint64_t const flags) noexcept {
return downcast(this)->createSwapChain(nativeWindow, flags);
}
SwapChain* Engine::createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept {
SwapChain* Engine::createSwapChain(uint32_t const width, uint32_t const height, uint64_t const flags) noexcept {
return downcast(this)->createSwapChain(width, height, flags);
}
@@ -204,7 +204,7 @@ bool Engine::destroy(const InstanceBuffer* p) {
return downcast(this)->destroy(downcast(p));
}
void Engine::destroy(Entity e) {
void Engine::destroy(Entity const e) {
downcast(this)->destroy(e);
}
@@ -338,11 +338,15 @@ void Engine::flushAndWait() {
downcast(this)->flushAndWait();
}
bool Engine::flushAndWait(uint64_t timeout) {
return downcast(this)->flushAndWait(timeout);
}
void Engine::flush() {
downcast(this)->flush();
}
utils::EntityManager& Engine::getEntityManager() noexcept {
EntityManager& Engine::getEntityManager() noexcept {
return downcast(this)->getEntityManager();
}
@@ -362,7 +366,7 @@ void Engine::enableAccurateTranslations() noexcept {
getTransformManager().setAccurateTranslationsEnabled(true);
}
void* Engine::streamAlloc(size_t size, size_t alignment) noexcept {
void* Engine::streamAlloc(size_t const size, size_t const alignment) noexcept {
return downcast(this)->streamAlloc(size, alignment);
}
@@ -375,7 +379,7 @@ void Engine::execute() {
downcast(this)->execute();
}
utils::JobSystem& Engine::getJobSystem() noexcept {
JobSystem& Engine::getJobSystem() noexcept {
return downcast(this)->getJobSystem();
}
@@ -385,7 +389,7 @@ bool Engine::isPaused() const noexcept {
return downcast(this)->isPaused();
}
void Engine::setPaused(bool paused) {
void Engine::setPaused(bool const paused) {
FILAMENT_CHECK_PRECONDITION(UTILS_HAS_THREADING)
<< "Pause is meant for multi-threaded platforms.";
downcast(this)->setPaused(paused);
@@ -403,7 +407,7 @@ void Engine::unprotected() noexcept {
downcast(this)->unprotected();
}
void Engine::setAutomaticInstancingEnabled(bool enable) noexcept {
void Engine::setAutomaticInstancingEnabled(bool const enable) noexcept {
downcast(this)->setAutomaticInstancingEnabled(enable);
}
@@ -415,7 +419,7 @@ FeatureLevel Engine::getSupportedFeatureLevel() const noexcept {
return downcast(this)->getSupportedFeatureLevel();
}
FeatureLevel Engine::setActiveFeatureLevel(FeatureLevel featureLevel) {
FeatureLevel Engine::setActiveFeatureLevel(FeatureLevel const featureLevel) {
return downcast(this)->setActiveFeatureLevel(featureLevel);
}
@@ -443,11 +447,11 @@ uint64_t Engine::getSteadyClockTimeNano() noexcept {
return std::chrono::steady_clock::now().time_since_epoch().count();
}
utils::Slice<const Engine::FeatureFlag> Engine::getFeatureFlags() const noexcept {
Slice<const Engine::FeatureFlag> Engine::getFeatureFlags() const noexcept {
return downcast(this)->getFeatureFlags();
}
bool Engine::setFeatureFlag(char const* name, bool value) noexcept {
bool Engine::setFeatureFlag(char const* name, bool const value) noexcept {
return downcast(this)->setFeatureFlag(name, value);
}
+9 -9
View File
@@ -28,7 +28,7 @@ float ev100(const Camera& c) noexcept {
return ev100(camera.getAperture(), camera.getShutterSpeed(), camera.getSensitivity());
}
float ev100(float aperture, float shutterSpeed, float sensitivity) noexcept {
float ev100(float const aperture, float const shutterSpeed, float const sensitivity) noexcept {
// With N = aperture, t = shutter speed and S = sensitivity,
// we can compute EV100 knowing that:
//
@@ -46,7 +46,7 @@ float ev100(float aperture, float shutterSpeed, float sensitivity) noexcept {
return std::log2((aperture * aperture) / shutterSpeed * 100.0f / sensitivity);
}
float ev100FromLuminance(float luminance) noexcept {
float ev100FromLuminance(float const luminance) noexcept {
// With L the average scene luminance, S the sensitivity and K the
// reflected-light meter calibration constant:
//
@@ -61,7 +61,7 @@ float ev100FromLuminance(float luminance) noexcept {
return std::log2(luminance * (100.0f / 12.5f));
}
float ev100FromIlluminance(float illuminance) noexcept {
float ev100FromIlluminance(float const illuminance) noexcept {
// With E the illuminance, S the sensitivity and C the incident-light meter
// calibration constant, the exposure value can be computed as such:
//
@@ -83,14 +83,14 @@ float exposure(const Camera& c) noexcept {
return exposure(camera.getAperture(), camera.getShutterSpeed(), camera.getSensitivity());
}
float exposure(float aperture, float shutterSpeed, float sensitivity) noexcept {
float exposure(float const aperture, float const shutterSpeed, float const sensitivity) noexcept {
// This is equivalent to calling exposure(ev100(N, t, S))
// By merging the two calls we can remove extra pow()/log2() calls
const float e = (aperture * aperture) / shutterSpeed * 100.0f / sensitivity;
return 1.0f / (1.2f * e);
}
float exposure(float ev100) noexcept {
float exposure(float const ev100) noexcept {
// The photometric exposure H is defined by:
//
// H = (q * t / (N^2)) * L
@@ -140,14 +140,14 @@ float luminance(const Camera& c) noexcept {
return luminance(camera.getAperture(), camera.getShutterSpeed(), camera.getSensitivity());
}
float luminance(float aperture, float shutterSpeed, float sensitivity) noexcept {
float luminance(float const aperture, float const shutterSpeed, float const sensitivity) noexcept {
// This is equivalent to calling luminance(ev100(N, t, S))
// By merging the two calls we can remove extra pow()/log2() calls
const float e = (aperture * aperture) / shutterSpeed * 100.0f / sensitivity;
return e * 0.125f;
}
float luminance(float ev100) noexcept {
float luminance(float const ev100) noexcept {
// With L the average scene luminance, S the sensitivity and K the
// reflected-light meter calibration constant:
//
@@ -172,14 +172,14 @@ float illuminance(const Camera& c) noexcept {
return illuminance(camera.getAperture(), camera.getShutterSpeed(), camera.getSensitivity());
}
float illuminance(float aperture, float shutterSpeed, float sensitivity) noexcept {
float illuminance(float const aperture, float const shutterSpeed, float const sensitivity) noexcept {
// This is equivalent to calling illuminance(ev100(N, t, S))
// By merging the two calls we can remove extra pow()/log2() calls
const float e = (aperture * aperture) / shutterSpeed * 100.0f / sensitivity;
return 2.5f * e;
}
float illuminance(float ev100) noexcept {
float illuminance(float const ev100) noexcept {
// With E the illuminance, S the sensitivity and C the incident-light meter
// calibration constant, the exposure value can be computed as such:
//
+2 -2
View File
@@ -20,11 +20,11 @@ namespace filament {
using namespace backend;
FenceStatus Fence::waitAndDestroy(Fence* fence, Mode mode) {
FenceStatus Fence::waitAndDestroy(Fence* fence, Mode const mode) {
return FFence::waitAndDestroy(downcast(fence), mode);
}
FenceStatus Fence::wait(Mode mode, uint64_t timeout) {
FenceStatus Fence::wait(Mode const mode, uint64_t const timeout) {
return downcast(this)->wait(mode, timeout);
}
+1 -1
View File
@@ -20,7 +20,7 @@
namespace filament {
void builderMakeName(utils::CString& outName, const char* name, size_t len) noexcept {
void builderMakeName(utils::CString& outName, const char* name, size_t const len) noexcept {
if (!name) {
return;
}
+2 -2
View File
@@ -172,9 +172,9 @@ void FrameInfoManager::denoiseFrameTime(FrameHistoryQueue& history, Config const
}
}
utils::FixedCapacityVector<Renderer::FrameInfo> FrameInfoManager::getFrameInfoHistory(
FixedCapacityVector<Renderer::FrameInfo> FrameInfoManager::getFrameInfoHistory(
size_t historySize) const noexcept {
auto result = utils::FixedCapacityVector<Renderer::FrameInfo>::with_capacity(MAX_FRAMETIME_HISTORY);
auto result = FixedCapacityVector<Renderer::FrameInfo>::with_capacity(MAX_FRAMETIME_HISTORY);
auto const& history = mFrameTimeHistory;
size_t i = 0;
size_t const c = history.size();
+3 -3
View File
@@ -57,7 +57,7 @@ struct FrameInfoImpl : public details::FrameInfo {
time_point backendBeginFrame; // backend thread beginFrame time (makeCurrent time)
time_point backendEndFrame; // backend thread endFrame time (present time)
std::atomic_bool ready{}; // true once backend thread has populated its data
explicit FrameInfoImpl(uint32_t frameId) noexcept
explicit FrameInfoImpl(uint32_t const frameId) noexcept
: frameId(frameId) {
}
};
@@ -110,7 +110,7 @@ public:
return front();
}
T& operator[](size_t pos) noexcept {
T& operator[](size_t const pos) noexcept {
assert_invariant(pos < size());
size_t const index = (mFront + CAPACITY - pos) % CAPACITY;
return *std::launder(reinterpret_cast<T*>(&mStorage[index]));
@@ -135,7 +135,7 @@ private:
Storage mStorage[CAPACITY];
uint32_t mFront = 0; // always index 0
uint32_t mSize = 0;
[[nodiscard]] inline uint32_t advance(uint32_t v) noexcept {
[[nodiscard]] inline uint32_t advance(uint32_t const v) noexcept {
return (v + 1) % CAPACITY;
}
};
+1 -1
View File
@@ -30,7 +30,7 @@ namespace filament {
using namespace utils;
using namespace backend;
FrameSkipper::FrameSkipper(size_t latency) noexcept
FrameSkipper::FrameSkipper(size_t const latency) noexcept
: mLast(std::clamp(latency, size_t(1), MAX_FRAME_LATENCY) - 1) {
}
+42 -22
View File
@@ -16,27 +16,47 @@
#include "Froxelizer.h"
#include "Allocators.h"
#include "Intersections.h"
#include "details/Engine.h"
#include "details/Scene.h"
#include "private/backend/DriverApi.h"
#include <private/filament/EngineEnums.h>
#include <private/backend/DriverApi.h>
#include <filament/Box.h>
#include <filament/Viewport.h>
#include <backend/DriverEnums.h>
#include <utils/BinaryTreeArray.h>
#include <utils/JobSystem.h>
#include <utils/Log.h>
#include <utils/Slice.h>
#include <utils/Systrace.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <math/mat4.h>
#include <math/fast.h>
#include <math/mat3.h>
#include <math/mat4.h>
#include <math/scalar.h>
#include <math/vec2.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <algorithm>
#include <utils/architecture.h>
#include <array>
#include <cmath>
#include <limits>
#include <type_traits>
#include <utility>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
using namespace filament::math;
using namespace utils;
@@ -143,7 +163,7 @@ void Froxelizer::terminate(DriverApi& driverApi) noexcept {
}
}
void Froxelizer::setOptions(float zLightNear, float zLightFar) noexcept {
void Froxelizer::setOptions(float const zLightNear, float const zLightFar) noexcept {
if (UTILS_UNLIKELY(mZLightNear != zLightNear || mZLightFar != zLightFar)) {
mZLightNear = zLightNear;
mZLightFar = zLightFar;
@@ -160,7 +180,7 @@ void Froxelizer::setViewport(filament::Viewport const& viewport) noexcept {
}
void Froxelizer::setProjection(const mat4f& projection,
float near, UTILS_UNUSED float far) noexcept {
float const near, UTILS_UNUSED float far) noexcept {
if (UTILS_UNLIKELY(!fuzzyEqual(mProjection, projection))) {
mProjection = projection;
mNear = near;
@@ -171,7 +191,7 @@ void Froxelizer::setProjection(const mat4f& projection,
bool Froxelizer::prepare(
FEngine::DriverApi& driverApi, RootArenaScope& rootArenaScope,
filament::Viewport const& viewport,
const mat4f& projection, float projectionNear, float projectionFar) noexcept {
const mat4f& projection, float const projectionNear, float const projectionFar) noexcept {
setViewport(viewport);
setProjection(projection, projectionNear, projectionFar);
@@ -223,9 +243,9 @@ bool Froxelizer::prepare(
void Froxelizer::computeFroxelLayout(
uint2* dim, uint16_t* countX, uint16_t* countY, uint16_t* countZ,
size_t froxelBufferEntryCount, filament::Viewport const& viewport) noexcept {
size_t const froxelBufferEntryCount, filament::Viewport const& viewport) noexcept {
auto roundTo8 = [](uint32_t v) { return (v + 7u) & ~7u; };
auto roundTo8 = [](uint32_t const v) { return (v + 7u) & ~7u; };
const uint32_t width = std::max(16u, viewport.width);
const uint32_t height = std::max(16u, viewport.height);
@@ -264,10 +284,10 @@ void Froxelizer::computeFroxelLayout(
UTILS_NOINLINE
void Froxelizer::updateBoundingSpheres(
math::float4* const UTILS_RESTRICT boundingSpheres,
float4* const UTILS_RESTRICT boundingSpheres,
size_t froxelCountX, size_t froxelCountY, size_t froxelCountZ,
math::float4 const* UTILS_RESTRICT planesX,
math::float4 const* UTILS_RESTRICT planesY,
float4 const* UTILS_RESTRICT planesX,
float4 const* UTILS_RESTRICT planesY,
float const* UTILS_RESTRICT planesZ) noexcept {
SYSTRACE_CALL();
@@ -458,7 +478,7 @@ bool Froxelizer::update() noexcept {
return uniformsNeedUpdating;
}
Froxel Froxelizer::getFroxelAt(size_t x, size_t y, size_t z) const noexcept {
Froxel Froxelizer::getFroxelAt(size_t const x, size_t const y, size_t const z) const noexcept {
assert_invariant(x < mFroxelCountX);
assert_invariant(y < mFroxelCountY);
assert_invariant(z < mFroxelCountZ);
@@ -473,7 +493,7 @@ Froxel Froxelizer::getFroxelAt(size_t x, size_t y, size_t z) const noexcept {
}
UTILS_NOINLINE
size_t Froxelizer::findSliceZ(float z) const noexcept {
size_t Froxelizer::findSliceZ(float const z) const noexcept {
// The vastly common case is that z<0, so we always do the math for this case
// and we "undo" it below otherwise. This works because we're using fast::log2 which
// doesn't care if given a negative number (we'd have to use abs() otherwise).
@@ -502,7 +522,7 @@ std::pair<size_t, size_t> Froxelizer::clipToIndices(float2 const& clip) const no
}
void Froxelizer::commit(backend::DriverApi& driverApi) {
void Froxelizer::commit(DriverApi& driverApi) {
// send data to GPU
driverApi.updateBufferObject(mFroxelsBuffer,
{ mFroxelBufferUser.data(), getFroxelBufferEntryCount() * 16u }, 0);
@@ -563,7 +583,7 @@ void Froxelizer::froxelizeLoop(FEngine& engine,
auto process = [ this, &froxelThreadData,
spheres, directions, instances, &viewMatrix, &lcm ]
(size_t count, size_t offset, size_t stride) {
(size_t const count, size_t const offset, size_t const stride) {
SYSTRACE_NAME("FroxelizeLoop Job");
@@ -603,7 +623,7 @@ void Froxelizer::froxelizeLoop(FEngine& engine,
JobSystem& js = engine.getJobSystem();
constexpr bool SINGLE_THREADED = false;
if (!SINGLE_THREADED) {
if constexpr (!SINGLE_THREADED) {
auto *parent = js.createJob();
for (size_t i = 0; i < GROUP_COUNT; i++) {
js.run(jobs::createJob(js, parent, std::cref(process),
@@ -629,7 +649,7 @@ void Froxelizer::froxelizeAssignRecordsCompress() noexcept {
// this gets very well vectorized...
utils::Slice<LightRecord> records(mLightRecords);
Slice<LightRecord> records(mLightRecords);
for (size_t j = 0, jc = getFroxelBufferEntryCount(); j < jc; j++) {
for (size_t i = 0; i < LightRecord::bitset::WORLD_COUNT; i++) {
using container_type = LightRecord::bitset::container_type;
@@ -737,7 +757,7 @@ out_of_memory:
;
}
static inline float2 project(mat4f const& p, float3 const& v) noexcept {
static float2 project(mat4f const& p, float3 const& v) noexcept {
const float vx = v[0];
const float vy = v[1];
const float vz = v[2];
@@ -750,7 +770,7 @@ static inline float2 project(mat4f const& p, float3 const& v) noexcept {
void Froxelizer::froxelizePointAndSpotLight(
FroxelThreadData& froxelThread, size_t bit,
mat4f const& UTILS_RESTRICT p,
const Froxelizer::LightParams& UTILS_RESTRICT light) const noexcept {
const LightParams& UTILS_RESTRICT light) const noexcept {
if (UTILS_UNLIKELY(light.position.z + light.radius < -mZLightFar)) { // z values are negative
// This light is fully behind LightFar, it doesn't light anything
@@ -902,7 +922,7 @@ void Froxelizer::froxelizePointAndSpotLight(
*/
void Froxelizer::computeLightTree(
LightTreeNode* lightTree,
utils::Slice<RecordBufferType> const& lightList,
Slice<RecordBufferType> const& lightList,
const FScene::LightSoa& lightData,
size_t lightRecordsOffset) noexcept {
@@ -910,7 +930,7 @@ void Froxelizer::computeLightTree(
const size_t count = lightList.size();
// the width of the tree is the next power-of-two (if not already a power of two)
const size_t w = 1u << (log2i(count) + (utils::popcount(count) == 1 ? 0 : 1));
const size_t w = 1u << (log2i(count) + (popcount(count) == 1 ? 0 : 1));
// height of the tree
const size_t h = log2i(w) + 1u;
@@ -918,7 +938,7 @@ void Froxelizer::computeLightTree(
auto const* UTILS_RESTRICT zrange = lightData.data<FScene::SCREEN_SPACE_Z_RANGE>() + 1;
BinaryTreeArray::traverse(h,
[lightTree, lightRecordsOffset, zrange, indices = lightList.data(), count]
(size_t index, size_t col, size_t next) {
(size_t const index, size_t const col, size_t const next) {
// indices[] cannot be accessed past 'col'
const float min = (col < count) ? zrange[indices[col]].x : 1.0f;
const float max = (col < count) ? zrange[indices[col]].y : 0.0f;
@@ -932,7 +952,7 @@ void Froxelizer::computeLightTree(
.reserved = 0,
};
},
[lightTree](size_t index, size_t l, size_t r, size_t next) {
[lightTree](size_t const index, size_t const l, size_t const r, size_t const next) {
lightTree[index] = {
.min = std::min(lightTree[l].min, lightTree[r].min),
.max = std::max(lightTree[l].max, lightTree[r].max),
+4 -4
View File
@@ -140,7 +140,7 @@ public:
*/
struct FroxelEntry {
inline FroxelEntry(uint16_t offset, uint8_t count) noexcept
inline FroxelEntry(uint16_t const offset, uint8_t const count) noexcept
: u32((offset << 16) | count) { }
inline uint8_t count() const noexcept { return u32 & 0xFFu; }
inline uint16_t offset() const noexcept { return u32 >> 16u; }
@@ -214,12 +214,12 @@ private:
math::float4 const* UTILS_RESTRICT planesY,
float const* UTILS_RESTRICT planesZ) noexcept;
static size_t getFroxelIndex(size_t ix, size_t iy, size_t iz,
size_t froxelCountX, size_t froxelCountY) noexcept {
static size_t getFroxelIndex(size_t const ix, size_t const iy, size_t const iz,
size_t const froxelCountX, size_t const froxelCountY) noexcept {
return ix + (iy * froxelCountX) + (iz * froxelCountX * froxelCountY);
}
size_t getFroxelIndex(size_t ix, size_t iy, size_t iz) const noexcept {
size_t getFroxelIndex(size_t const ix, size_t const iy, size_t const iz) const noexcept {
return getFroxelIndex(ix, iy, iz, mFroxelCountX, mFroxelCountY);
}
+10 -4
View File
@@ -19,14 +19,20 @@
#include "Culler.h"
#include <utils/compiler.h>
#include <utils/Log.h>
#include <utils/ostream.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <math/mat4.h>
#include <algorithm>
using namespace filament::math;
namespace filament {
Frustum::Frustum(const mat4f& pv) {
Frustum::setProjection(pv);
setProjection(pv);
}
// NOTE: if we don't specify noinline here, LLVM inlines this huge function into
@@ -68,7 +74,7 @@ void Frustum::setProjection(const mat4f& pv) {
mPlanes[5] = n;
}
float4 Frustum::getNormalizedPlane(Frustum::Plane plane) const noexcept {
float4 Frustum::getNormalizedPlane(Plane plane) const noexcept {
return mPlanes[size_t(plane)];
}
@@ -89,7 +95,7 @@ bool Frustum::intersects(const float4& sphere) const noexcept {
return Culler::intersects(*this, sphere);
}
float Frustum::contains(float3 p) const noexcept {
float Frustum::contains(float3 const p) const noexcept {
float const l = dot(mPlanes[0].xyz, p) + mPlanes[0].w;
float const b = dot(mPlanes[1].xyz, p) + mPlanes[1].w;
float const r = dot(mPlanes[2].xyz, p) + mPlanes[2].w;
@@ -39,9 +39,9 @@ using namespace utils;
using namespace backend;
size_t HwDescriptorSetLayoutFactory::Parameters::hash() const noexcept {
return utils::hash::murmurSlow(
return hash::murmurSlow(
reinterpret_cast<uint8_t const *>(dsl.bindings.data()),
dsl.bindings.size() * sizeof(backend::DescriptorSetLayoutBinding),
dsl.bindings.size() * sizeof(DescriptorSetLayoutBinding),
42);
}
@@ -68,7 +68,7 @@ void HwDescriptorSetLayoutFactory::terminate(DriverApi&) noexcept {
}
auto HwDescriptorSetLayoutFactory::create(DriverApi& driver,
backend::DescriptorSetLayout dsl) noexcept -> Handle {
DescriptorSetLayout dsl) noexcept -> Handle {
std::sort(dsl.bindings.begin(), dsl.bindings.end(),
[](auto&& lhs, auto&& rhs) {
+5 -5
View File
@@ -34,8 +34,8 @@ using namespace utils;
using namespace backend;
size_t HwRenderPrimitiveFactory::Parameters::hash() const noexcept {
return utils::hash::combine(vbh.getId(),
utils::hash::combine(ibh.getId(),
return hash::combine(vbh.getId(),
hash::combine(ibh.getId(),
(size_t)type));
}
@@ -61,9 +61,9 @@ void HwRenderPrimitiveFactory::terminate(DriverApi&) noexcept {
}
auto HwRenderPrimitiveFactory::create(DriverApi& driver,
backend::VertexBufferHandle vbh,
backend::IndexBufferHandle ibh,
backend::PrimitiveType type) noexcept -> Handle {
VertexBufferHandle vbh,
IndexBufferHandle ibh,
PrimitiveType const type) noexcept -> Handle {
// see if we already have seen this RenderPrimitive
Key const key({ vbh, ibh, type });
+4 -4
View File
@@ -37,7 +37,7 @@ using namespace backend;
size_t HwVertexBufferInfoFactory::Parameters::hash() const noexcept {
static_assert((sizeof(*this) % sizeof(uint32_t)) == 0);
return utils::hash::murmur3(
return hash::murmur3(
reinterpret_cast<uint32_t const*>(this), sizeof(Parameters) / sizeof(uint32_t), 0);
}
@@ -61,9 +61,9 @@ void HwVertexBufferInfoFactory::terminate(DriverApi&) noexcept {
}
auto HwVertexBufferInfoFactory::create(DriverApi& driver,
uint8_t bufferCount,
uint8_t attributeCount,
backend::AttributeArray attributes) noexcept -> Handle {
uint8_t const bufferCount,
uint8_t const attributeCount,
AttributeArray attributes) noexcept -> Handle {
Key const key({ bufferCount, attributeCount, {}, attributes });
auto pos = mBimap.find(key);
+1 -1
View File
@@ -21,7 +21,7 @@
namespace filament {
void IndexBuffer::setBuffer(Engine& engine,
IndexBuffer::BufferDescriptor&& buffer, uint32_t byteOffset) {
BufferDescriptor&& buffer, uint32_t const byteOffset) {
downcast(this)->setBuffer(downcast(engine), std::move(buffer), byteOffset);
}
+3 -3
View File
@@ -22,7 +22,7 @@ namespace filament {
using namespace math;
void IndirectLight::setIntensity(float intensity) noexcept {
void IndirectLight::setIntensity(float const intensity) noexcept {
downcast(this)->setIntensity(intensity);
}
@@ -50,7 +50,7 @@ float3 IndirectLight::getDirectionEstimate() const noexcept {
return downcast(this)->getDirectionEstimate();
}
float4 IndirectLight::getColorEstimate(float3 direction) const noexcept {
float4 IndirectLight::getColorEstimate(float3 const direction) const noexcept {
return downcast(this)->getColorEstimate(direction);
}
@@ -58,7 +58,7 @@ float3 IndirectLight::getDirectionEstimate(const float3* sh) noexcept {
return FIndirectLight::getDirectionEstimate(sh);
}
float4 IndirectLight::getColorEstimate(const float3* sh, float3 direction) noexcept {
float4 IndirectLight::getColorEstimate(const float3* sh, float3 const direction) noexcept {
return FIndirectLight::getColorEstimate(sh, direction);
}
+1 -1
View File
@@ -23,7 +23,7 @@ size_t InstanceBuffer::getInstanceCount() const noexcept {
}
void InstanceBuffer::setLocalTransforms(
math::mat4f const* localTransforms, size_t count, size_t offset) {
math::mat4f const* localTransforms, size_t const count, size_t const offset) {
downcast(this)->setLocalTransforms(localTransforms, count, offset);
}
+3 -3
View File
@@ -40,7 +40,7 @@ inline constexpr math::float4 spherePlaneIntersection(math::float4 s, math::floa
// sphere radius must be squared
// plane equation must be normalized and have the form {0,0,1,w}, sphere radius must be squared
// return float4.w <= 0 if no intersection
inline constexpr math::float4 spherePlaneIntersection(math::float4 s, float pw) noexcept {
inline constexpr math::float4 spherePlaneIntersection(math::float4 const s, float pw) noexcept {
return spherePlaneIntersection(s, { 0.f, 0.f, 1.f, pw });
}
@@ -65,8 +65,8 @@ inline constexpr bool sphereConeIntersection(
math::float4 const& sphere,
math::float3 const& conePosition,
math::float3 const& coneAxis,
float coneSinInverse,
float coneCosSquared) noexcept {
float const coneSinInverse,
float const coneCosSquared) noexcept {
if (sphereConeIntersectionFast(sphere,
conePosition, coneAxis, coneSinInverse, coneCosSquared)) {
math::float3 const d = sphere.xyz - conePosition;
+32 -32
View File
@@ -22,7 +22,7 @@ namespace filament {
using namespace math;
bool LightManager::hasComponent(Entity e) const noexcept {
bool LightManager::hasComponent(Entity const e) const noexcept {
return downcast(this)->hasComponent(e);
}
@@ -34,128 +34,128 @@ bool LightManager::empty() const noexcept {
return downcast(this)->empty();
}
utils::Entity LightManager::getEntity(LightManager::Instance i) const noexcept {
Entity LightManager::getEntity(Instance const i) const noexcept {
return downcast(this)->getEntity(i);
}
utils::Entity const* LightManager::getEntities() const noexcept {
Entity const* LightManager::getEntities() const noexcept {
return downcast(this)->getEntities();
}
LightManager::Instance LightManager::getInstance(Entity e) const noexcept {
LightManager::Instance LightManager::getInstance(Entity const e) const noexcept {
return downcast(this)->getInstance(e);
}
void LightManager::destroy(Entity e) noexcept {
void LightManager::destroy(Entity const e) noexcept {
return downcast(this)->destroy(e);
}
void LightManager::setLightChannel(Instance i, unsigned int channel, bool enable) noexcept {
void LightManager::setLightChannel(Instance const i, unsigned int const channel, bool const enable) noexcept {
downcast(this)->setLightChannel(i, channel, enable);
}
bool LightManager::getLightChannel(LightManager::Instance i, unsigned int channel) const noexcept {
bool LightManager::getLightChannel(Instance const i, unsigned int const channel) const noexcept {
return downcast(this)->getLightChannel(i, channel);
}
void LightManager::setPosition(Instance i, const float3& position) noexcept {
void LightManager::setPosition(Instance const i, const float3& position) noexcept {
downcast(this)->setLocalPosition(i, position);
}
const float3& LightManager::getPosition(Instance i) const noexcept {
const float3& LightManager::getPosition(Instance const i) const noexcept {
return downcast(this)->getLocalPosition(i);
}
void LightManager::setDirection(Instance i, const float3& direction) noexcept {
void LightManager::setDirection(Instance const i, const float3& direction) noexcept {
downcast(this)->setLocalDirection(i, direction);
}
const float3& LightManager::getDirection(Instance i) const noexcept {
const float3& LightManager::getDirection(Instance const i) const noexcept {
return downcast(this)->getLocalDirection(i);
}
void LightManager::setColor(Instance i, const LinearColor& color) noexcept {
void LightManager::setColor(Instance const i, const LinearColor& color) noexcept {
downcast(this)->setColor(i, color);
}
const float3& LightManager::getColor(Instance i) const noexcept {
const float3& LightManager::getColor(Instance const i) const noexcept {
return downcast(this)->getColor(i);
}
void LightManager::setIntensity(Instance i, float intensity) noexcept {
void LightManager::setIntensity(Instance const i, float const intensity) noexcept {
downcast(this)->setIntensity(i, intensity, FLightManager::IntensityUnit::LUMEN_LUX);
}
void LightManager::setIntensityCandela(Instance i, float intensity) noexcept {
void LightManager::setIntensityCandela(Instance const i, float const intensity) noexcept {
downcast(this)->setIntensity(i, intensity, FLightManager::IntensityUnit::CANDELA);
}
float LightManager::getIntensity(Instance i) const noexcept {
float LightManager::getIntensity(Instance const i) const noexcept {
return downcast(this)->getIntensity(i);
}
void LightManager::setFalloff(Instance i, float radius) noexcept {
void LightManager::setFalloff(Instance const i, float const radius) noexcept {
downcast(this)->setFalloff(i, radius);
}
float LightManager::getFalloff(Instance i) const noexcept {
float LightManager::getFalloff(Instance const i) const noexcept {
return downcast(this)->getFalloff(i);
}
void LightManager::setSpotLightCone(Instance i, float inner, float outer) noexcept {
void LightManager::setSpotLightCone(Instance const i, float const inner, float const outer) noexcept {
downcast(this)->setSpotLightCone(i, inner, outer);
}
float LightManager::getSpotLightOuterCone(Instance i) const noexcept {
float LightManager::getSpotLightOuterCone(Instance const i) const noexcept {
return downcast(this)->getSpotParams(i).outerClamped;
}
float LightManager::getSpotLightInnerCone(Instance i) const noexcept {
float LightManager::getSpotLightInnerCone(Instance const i) const noexcept {
return downcast(this)->getSpotLightInnerCone(i);
}
void LightManager::setSunAngularRadius(Instance i, float angularRadius) noexcept {
void LightManager::setSunAngularRadius(Instance const i, float const angularRadius) noexcept {
downcast(this)->setSunAngularRadius(i, angularRadius);
}
float LightManager::getSunAngularRadius(Instance i) const noexcept {
float LightManager::getSunAngularRadius(Instance const i) const noexcept {
float radius = downcast(this)->getSunAngularRadius(i);
return radius * f::RAD_TO_DEG;
}
void LightManager::setSunHaloSize(Instance i, float haloSize) noexcept {
void LightManager::setSunHaloSize(Instance const i, float const haloSize) noexcept {
downcast(this)->setSunHaloSize(i, haloSize);
}
float LightManager::getSunHaloSize(Instance i) const noexcept {
float LightManager::getSunHaloSize(Instance const i) const noexcept {
return downcast(this)->getSunHaloSize(i);
}
void LightManager::setSunHaloFalloff(Instance i, float haloFalloff) noexcept {
void LightManager::setSunHaloFalloff(Instance const i, float const haloFalloff) noexcept {
downcast(this)->setSunHaloFalloff(i, haloFalloff);
}
float LightManager::getSunHaloFalloff(Instance i) const noexcept {
float LightManager::getSunHaloFalloff(Instance const i) const noexcept {
return downcast(this)->getSunHaloFalloff(i);
}
LightManager::Type LightManager::getType(LightManager::Instance i) const noexcept {
LightManager::Type LightManager::getType(Instance const i) const noexcept {
return downcast(this)->getType(i);
}
const LightManager::ShadowOptions& LightManager::getShadowOptions(Instance i) const noexcept {
const LightManager::ShadowOptions& LightManager::getShadowOptions(Instance const i) const noexcept {
return downcast(this)->getShadowOptions(i);
}
void LightManager::setShadowOptions(Instance i, ShadowOptions const& options) noexcept {
void LightManager::setShadowOptions(Instance const i, ShadowOptions const& options) noexcept {
downcast(this)->setShadowOptions(i, options);
}
bool LightManager::isShadowCaster(Instance i) const noexcept {
bool LightManager::isShadowCaster(Instance const i) const noexcept {
return downcast(this)->isShadowCaster(i);
}
void LightManager::setShadowCaster(Instance i, bool castShadows) noexcept {
void LightManager::setShadowCaster(Instance const i, bool const castShadows) noexcept {
downcast(this)->setShadowCaster(i, castShadows);
}
+18 -4
View File
@@ -16,8 +16,22 @@
#include "details/Material.h"
#include <filament/Material.h>
#include <filament/MaterialEnums.h>
#include <backend/CallbackHandler.h>
#include <backend/DriverEnums.h>
#include <utils/Invocable.h>
#include <utility>
#include <stddef.h>
namespace filament {
class MaterialInstance;
using namespace backend;
MaterialInstance* Material::createInstance(const char* name) const noexcept {
@@ -100,7 +114,7 @@ size_t Material::getParameterCount() const noexcept {
return downcast(this)->getParameterCount();
}
size_t Material::getParameters(ParameterInfo* parameters, size_t count) const noexcept {
size_t Material::getParameters(ParameterInfo* parameters, size_t const count) const noexcept {
return downcast(this)->getParameters(parameters, count);
}
@@ -140,9 +154,9 @@ MaterialInstance const* Material::getDefaultInstance() const noexcept {
return downcast(this)->getDefaultInstance();
}
void Material::compile(CompilerPriorityQueue priority, UserVariantFilterMask variantFilter,
backend::CallbackHandler* handler, utils::Invocable<void(Material*)>&& callback) noexcept {
downcast(this)->compile(priority, variantFilter, handler, std::move(callback));
void Material::compile(CompilerPriorityQueue const priority, UserVariantFilterMask const variants,
CallbackHandler* handler, utils::Invocable<void(Material*)>&& callback) noexcept {
downcast(this)->compile(priority, variants, handler, std::move(callback));
}
UserVariantFilterMask Material::getSupportedVariants() const noexcept {
+50 -50
View File
@@ -29,7 +29,7 @@ using namespace backend;
// vec4<float>. This must not be inlined (this is the whole point).
template<size_t Size>
UTILS_NOINLINE
void FMaterialInstance::setParameterUntypedImpl(std::string_view name, const void* value) {
void FMaterialInstance::setParameterUntypedImpl(std::string_view const name, const void* value) {
ssize_t offset = mMaterial->getUniformInterfaceBlock().getFieldOffset(name, 0);
if (UTILS_LIKELY(offset >= 0)) {
mUniforms.setUniformUntyped<Size>(size_t(offset), value); // handles specialization for mat3f
@@ -41,14 +41,14 @@ void FMaterialInstance::setParameterUntypedImpl(std::string_view name, const voi
// this converts typed calls into the untyped-sized call.
template<typename T>
UTILS_ALWAYS_INLINE
inline void FMaterialInstance::setParameterImpl(std::string_view name, T const& value) {
static_assert(!std::is_same_v<T, math::mat3f>);
inline void FMaterialInstance::setParameterImpl(std::string_view const name, T const& value) {
static_assert(!std::is_same_v<T, mat3f>);
setParameterUntypedImpl<sizeof(T)>(name, &value);
}
// specialization for mat3f
template<>
inline void FMaterialInstance::setParameterImpl(std::string_view name, mat3f const& value) {
inline void FMaterialInstance::setParameterImpl(std::string_view const name, mat3f const& value) {
ssize_t offset = mMaterial->getUniformInterfaceBlock().getFieldOffset(name, 0);
if (UTILS_LIKELY(offset >= 0)) {
mUniforms.setUniform(size_t(offset), value);
@@ -59,8 +59,8 @@ inline void FMaterialInstance::setParameterImpl(std::string_view name, mat3f con
template<size_t Size>
UTILS_NOINLINE
void FMaterialInstance::setParameterUntypedImpl(std::string_view name,
const void* value, size_t count) {
void FMaterialInstance::setParameterUntypedImpl(std::string_view const name,
const void* value, size_t const count) {
ssize_t offset = mMaterial->getUniformInterfaceBlock().getFieldOffset(name, 0);
if (UTILS_LIKELY(offset >= 0)) {
mUniforms.setUniformArrayUntyped<Size>(size_t(offset), value, count);
@@ -69,9 +69,9 @@ void FMaterialInstance::setParameterUntypedImpl(std::string_view name,
template<typename T>
UTILS_ALWAYS_INLINE
inline void FMaterialInstance::setParameterImpl(std::string_view name,
const T* value, size_t count) {
static_assert(!std::is_same_v<T, math::mat3f>);
inline void FMaterialInstance::setParameterImpl(std::string_view const name,
const T* value, size_t const count) {
static_assert(!std::is_same_v<T, mat3f>);
setParameterUntypedImpl<sizeof(T)>(name, value, count);
}
@@ -83,27 +83,27 @@ void MaterialInstance::setParameter(const char* name, size_t nameLength, T const
}
template<>
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t nameLength, bool const& v) {
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t const nameLength, bool const& v) {
// this kills tail-call optimization
MaterialInstance::setParameter(name, nameLength, (uint32_t)v);
setParameter(name, nameLength, (uint32_t)v);
}
template<>
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t nameLength, bool2 const& v) {
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t const nameLength, bool2 const& v) {
// this kills tail-call optimization
MaterialInstance::setParameter(name, nameLength, uint2(v));
setParameter(name, nameLength, uint2(v));
}
template<>
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t nameLength, bool3 const& v) {
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t const nameLength, bool3 const& v) {
// this kills tail-call optimization
MaterialInstance::setParameter(name, nameLength, uint3(v));
setParameter(name, nameLength, uint3(v));
}
template<>
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t nameLength, bool4 const& v) {
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t const nameLength, bool4 const& v) {
// this kills tail-call optimization
MaterialInstance::setParameter(name, nameLength, uint4(v));
setParameter(name, nameLength, uint4(v));
}
// explicit template instantiation of our supported types
@@ -130,41 +130,41 @@ void MaterialInstance::setParameter(const char* name, size_t nameLength, const T
}
template<>
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t nameLength, const bool* v, size_t c) {
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t const nameLength, const bool* v, size_t const c) {
auto* p = new uint32_t[c];
std::copy_n(v, c, p);
MaterialInstance::setParameter(name, nameLength, p, c);
setParameter(name, nameLength, p, c);
delete [] p;
}
template<>
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t nameLength, const bool2* v, size_t c) {
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t const nameLength, const bool2* v, size_t const c) {
auto* p = new uint2[c];
std::copy_n(v, c, p);
MaterialInstance::setParameter(name, nameLength, p, c);
setParameter(name, nameLength, p, c);
delete [] p;
}
template<>
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t nameLength, const bool3* v, size_t c) {
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t const nameLength, const bool3* v, size_t const c) {
auto* p = new uint3[c];
std::copy_n(v, c, p);
MaterialInstance::setParameter(name, nameLength, p, c);
setParameter(name, nameLength, p, c);
delete [] p;
}
template<>
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t nameLength, const bool4* v, size_t c) {
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t const nameLength, const bool4* v, size_t const c) {
auto* p = new uint4[c];
std::copy_n(v, c, p);
MaterialInstance::setParameter(name, nameLength, p, c);
setParameter(name, nameLength, p, c);
delete [] p;
}
template<>
UTILS_PUBLIC void MaterialInstance::setParameter<mat3f>(const char* name, size_t nameLength, const mat3f* v, size_t c) {
UTILS_PUBLIC void MaterialInstance::setParameter<mat3f>(const char* name, size_t const nameLength, const mat3f* v, size_t const c) {
// pretend each mat3 is an array of 3 float3
MaterialInstance::setParameter(name, nameLength, reinterpret_cast<math::float3 const*>(v), c * 3);
setParameter(name, nameLength, reinterpret_cast<float3 const*>(v), c * 3);
}
template UTILS_PUBLIC void MaterialInstance::setParameter<float> (const char* name, size_t nameLength, const float *v, size_t c);
@@ -184,7 +184,7 @@ template UTILS_PUBLIC void MaterialInstance::setParameter<mat4f> (const char*
// ------------------------------------------------------------------------------------------------
template<typename T>
T FMaterialInstance::getParameterImpl(std::string_view name) const {
T FMaterialInstance::getParameterImpl(std::string_view const name) const {
ssize_t offset = mMaterial->getUniformInterfaceBlock().getFieldOffset(name, 0);
assert_invariant(offset>=0);
return downcast(this)->getUniformBuffer().getUniform<T>(offset);
@@ -226,17 +226,17 @@ void MaterialInstance::setParameter(const char* name, size_t nameLength, Texture
}
void MaterialInstance::setParameter(
const char* name, size_t nameLength, RgbType type, float3 color) {
const char* name, size_t nameLength, RgbType const type, float3 const color) {
downcast(this)->setParameterImpl<float3>({ name, nameLength }, Color::toLinear(type, color));
}
void MaterialInstance::setParameter(
const char* name, size_t nameLength, RgbaType type, float4 color) {
const char* name, size_t nameLength, RgbaType const type, float4 const color) {
downcast(this)->setParameterImpl<float4>({ name, nameLength }, Color::toLinear(type, color));
}
void MaterialInstance::setScissor(
uint32_t left, uint32_t bottom, uint32_t width, uint32_t height) noexcept {
uint32_t const left, uint32_t const bottom, uint32_t const width, uint32_t const height) noexcept {
downcast(this)->setScissor(left, bottom, width, height);
}
@@ -244,47 +244,47 @@ void MaterialInstance::unsetScissor() noexcept {
downcast(this)->unsetScissor();
}
void MaterialInstance::setPolygonOffset(float scale, float constant) noexcept {
void MaterialInstance::setPolygonOffset(float const scale, float const constant) noexcept {
downcast(this)->setPolygonOffset(scale, constant);
}
void MaterialInstance::setMaskThreshold(float threshold) noexcept {
void MaterialInstance::setMaskThreshold(float const threshold) noexcept {
downcast(this)->setMaskThreshold(threshold);
}
void MaterialInstance::setSpecularAntiAliasingVariance(float variance) noexcept {
void MaterialInstance::setSpecularAntiAliasingVariance(float const variance) noexcept {
downcast(this)->setSpecularAntiAliasingVariance(variance);
}
void MaterialInstance::setSpecularAntiAliasingThreshold(float threshold) noexcept {
void MaterialInstance::setSpecularAntiAliasingThreshold(float const threshold) noexcept {
downcast(this)->setSpecularAntiAliasingThreshold(threshold);
}
void MaterialInstance::setDoubleSided(bool doubleSided) noexcept {
void MaterialInstance::setDoubleSided(bool const doubleSided) noexcept {
downcast(this)->setDoubleSided(doubleSided);
}
void MaterialInstance::setTransparencyMode(TransparencyMode mode) noexcept {
void MaterialInstance::setTransparencyMode(TransparencyMode const mode) noexcept {
downcast(this)->setTransparencyMode(mode);
}
void MaterialInstance::setCullingMode(CullingMode culling) noexcept {
void MaterialInstance::setCullingMode(CullingMode const culling) noexcept {
downcast(this)->setCullingMode(culling);
}
void MaterialInstance::setColorWrite(bool enable) noexcept {
void MaterialInstance::setColorWrite(bool const enable) noexcept {
downcast(this)->setColorWrite(enable);
}
void MaterialInstance::setDepthWrite(bool enable) noexcept {
void MaterialInstance::setDepthWrite(bool const enable) noexcept {
downcast(this)->setDepthWrite(enable);
}
void MaterialInstance::setDepthCulling(bool enable) noexcept {
void MaterialInstance::setDepthCulling(bool const enable) noexcept {
downcast(this)->setDepthCulling(enable);
}
void MaterialInstance::setDepthFunc(DepthFunc depthFunc) noexcept {
void MaterialInstance::setDepthFunc(DepthFunc const depthFunc) noexcept {
downcast(this)->setDepthFunc(depthFunc);
}
@@ -292,35 +292,35 @@ MaterialInstance::DepthFunc MaterialInstance::getDepthFunc() const noexcept {
return downcast(this)->getDepthFunc();
}
void MaterialInstance::setStencilWrite(bool enable) noexcept {
void MaterialInstance::setStencilWrite(bool const enable) noexcept {
downcast(this)->setStencilWrite(enable);
}
void MaterialInstance::setStencilCompareFunction(StencilCompareFunc func, StencilFace face) noexcept {
void MaterialInstance::setStencilCompareFunction(StencilCompareFunc const func, StencilFace const face) noexcept {
downcast(this)->setStencilCompareFunction(func, face);
}
void MaterialInstance::setStencilOpStencilFail(StencilOperation op, StencilFace face) noexcept {
void MaterialInstance::setStencilOpStencilFail(StencilOperation const op, StencilFace const face) noexcept {
downcast(this)->setStencilOpStencilFail(op, face);
}
void MaterialInstance::setStencilOpDepthFail(StencilOperation op, StencilFace face) noexcept {
void MaterialInstance::setStencilOpDepthFail(StencilOperation const op, StencilFace const face) noexcept {
downcast(this)->setStencilOpDepthFail(op, face);
}
void MaterialInstance::setStencilOpDepthStencilPass(StencilOperation op, StencilFace face) noexcept {
void MaterialInstance::setStencilOpDepthStencilPass(StencilOperation const op, StencilFace const face) noexcept {
downcast(this)->setStencilOpDepthStencilPass(op, face);
}
void MaterialInstance::setStencilReferenceValue(uint8_t value, StencilFace face) noexcept {
void MaterialInstance::setStencilReferenceValue(uint8_t const value, StencilFace const face) noexcept {
downcast(this)->setStencilReferenceValue(value, face);
}
void MaterialInstance::setStencilReadMask(uint8_t readMask, StencilFace face) noexcept {
void MaterialInstance::setStencilReadMask(uint8_t const readMask, StencilFace const face) noexcept {
downcast(this)->setStencilReadMask(readMask, face);
}
void MaterialInstance::setStencilWriteMask(uint8_t writeMask, StencilFace face) noexcept {
void MaterialInstance::setStencilWriteMask(uint8_t const writeMask, StencilFace const face) noexcept {
downcast(this)->setStencilWriteMask(writeMask, face);
}
+79 -79
View File
@@ -54,26 +54,26 @@ using namespace filamat;
namespace filament {
constexpr std::pair<ChunkType, ChunkType> shaderLanguageToTags(ShaderLanguage language) {
constexpr std::pair<ChunkType, ChunkType> shaderLanguageToTags(ShaderLanguage const language) {
switch (language) {
case ShaderLanguage::ESSL3:
return { ChunkType::MaterialGlsl, ChunkType::DictionaryText };
return { MaterialGlsl, DictionaryText };
case ShaderLanguage::ESSL1:
return { ChunkType::MaterialEssl1, ChunkType::DictionaryText };
return { MaterialEssl1, DictionaryText };
case ShaderLanguage::MSL:
return { ChunkType::MaterialMetal, ChunkType::DictionaryText };
return { MaterialMetal, DictionaryText };
case ShaderLanguage::SPIRV:
return { ChunkType::MaterialSpirv, ChunkType::DictionarySpirv };
return { MaterialSpirv, DictionarySpirv };
case ShaderLanguage::METAL_LIBRARY:
return { ChunkType::MaterialMetalLibrary, ChunkType::DictionaryMetalLibrary };
return { MaterialMetalLibrary, DictionaryMetalLibrary };
}
}
// ------------------------------------------------------------------------------------------------
MaterialParser::MaterialParserDetails::MaterialParserDetails(
utils::FixedCapacityVector<ShaderLanguage> preferredLanguages, const void* data,
size_t size)
FixedCapacityVector<ShaderLanguage> preferredLanguages, const void* data,
size_t const size)
: mManagedBuffer(data, size),
mChunkContainer(mManagedBuffer.data(), mManagedBuffer.size()),
mPreferredLanguages(std::move(preferredLanguages)),
@@ -83,7 +83,7 @@ MaterialParser::MaterialParserDetails::MaterialParserDetails(
template<typename T>
UTILS_NOINLINE
bool MaterialParser::MaterialParserDetails::getFromSimpleChunk(
filamat::ChunkType type, T* value) const noexcept {
ChunkType const type, T* value) const noexcept {
ChunkContainer const& chunkContainer = mChunkContainer;
ChunkContainer::ChunkDesc chunkDesc;
if (chunkContainer.hasChunk(type, &chunkDesc)) {
@@ -93,7 +93,7 @@ bool MaterialParser::MaterialParserDetails::getFromSimpleChunk(
return false;
}
MaterialParser::MaterialParserDetails::ManagedBuffer::ManagedBuffer(const void* start, size_t size)
MaterialParser::MaterialParserDetails::ManagedBuffer::ManagedBuffer(const void* start, size_t const size)
: mStart(malloc(size)), mSize(size) {
memcpy(mStart, start, size);
}
@@ -108,12 +108,12 @@ template<typename T>
bool MaterialParser::get(typename T::Container* container) const noexcept {
auto [start, end] = mImpl.mChunkContainer.getChunkRange(T::tag);
if (start == end) return false;
filaflat::Unflattener unflattener{ start, end };
Unflattener unflattener{ start, end };
return T::unflatten(unflattener, container);
}
MaterialParser::MaterialParser(utils::FixedCapacityVector<ShaderLanguage> preferredLanguages,
const void* data, size_t size)
MaterialParser::MaterialParser(FixedCapacityVector<ShaderLanguage> preferredLanguages,
const void* data, size_t const size)
: mImpl(std::move(preferredLanguages), data, size) {
}
@@ -160,20 +160,20 @@ MaterialParser::ParseResult MaterialParser::parse() noexcept {
return ParseResult::SUCCESS;
}
backend::ShaderLanguage MaterialParser::getShaderLanguage() const noexcept {
ShaderLanguage MaterialParser::getShaderLanguage() const noexcept {
return mImpl.mChosenLanguage;
}
// Accessors
bool MaterialParser::getMaterialVersion(uint32_t* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialVersion, value);
return mImpl.getFromSimpleChunk(MaterialVersion, value);
}
bool MaterialParser::getFeatureLevel(uint8_t* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialFeatureLevel, value);
return mImpl.getFromSimpleChunk(MaterialFeatureLevel, value);
}
bool MaterialParser::getName(utils::CString* cstring) const noexcept {
bool MaterialParser::getName(CString* cstring) const noexcept {
auto [start, end] = mImpl.mChunkContainer.getChunkRange(MaterialName);
if (start == end) return false;
Unflattener unflattener(start, end);
@@ -200,11 +200,11 @@ bool MaterialParser::getSubpasses(SubpassInfo* container) const noexcept {
}
bool MaterialParser::getShaderModels(uint32_t* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialShaderModels, value);
return mImpl.getFromSimpleChunk(MaterialShaderModels, value);
}
bool MaterialParser::getMaterialProperties(uint64_t* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialProperties, value);
return mImpl.getFromSimpleChunk(MaterialProperties, value);
}
bool MaterialParser::getBindingUniformInfo(BindingUniformInfoContainer* container) const noexcept {
@@ -223,75 +223,75 @@ bool MaterialParser::getDescriptorSetLayout(DescriptorSetLayoutContainer* contai
return get<ChunkDescriptorSetLayoutInfo>(container);
}
bool MaterialParser::getConstants(utils::FixedCapacityVector<MaterialConstant>* container) const noexcept {
bool MaterialParser::getConstants(FixedCapacityVector<MaterialConstant>* container) const noexcept {
return get<ChunkMaterialConstants>(container);
}
bool MaterialParser::getPushConstants(utils::CString* structVarName,
utils::FixedCapacityVector<MaterialPushConstant>* value) const noexcept {
auto [start, end] = mImpl.mChunkContainer.getChunkRange(filamat::MaterialPushConstants);
bool MaterialParser::getPushConstants(CString* structVarName,
FixedCapacityVector<MaterialPushConstant>* value) const noexcept {
auto [start, end] = mImpl.mChunkContainer.getChunkRange(MaterialPushConstants);
if (start == end) return false;
Unflattener unflattener(start, end);
return ChunkMaterialPushConstants::unflatten(unflattener, structVarName, value);
}
bool MaterialParser::getDepthWriteSet(bool* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialDepthWriteSet, value);
return mImpl.getFromSimpleChunk(MaterialDepthWriteSet, value);
}
bool MaterialParser::getDepthWrite(bool* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialDepthWrite, value);
return mImpl.getFromSimpleChunk(MaterialDepthWrite, value);
}
bool MaterialParser::getDoubleSidedSet(bool* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialDoubleSidedSet, value);
return mImpl.getFromSimpleChunk(MaterialDoubleSidedSet, value);
}
bool MaterialParser::getDoubleSided(bool* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialDoubleSided, value);
return mImpl.getFromSimpleChunk(MaterialDoubleSided, value);
}
bool MaterialParser::getColorWrite(bool* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialColorWrite, value);
return mImpl.getFromSimpleChunk(MaterialColorWrite, value);
}
bool MaterialParser::getDepthTest(bool* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialDepthTest, value);
return mImpl.getFromSimpleChunk(MaterialDepthTest, value);
}
bool MaterialParser::getInstanced(bool* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialInstanced, value);
return mImpl.getFromSimpleChunk(MaterialInstanced, value);
}
bool MaterialParser::getCullingMode(CullingMode* value) const noexcept {
static_assert(sizeof(CullingMode) == sizeof(uint8_t),
"CullingMode expected size is wrong");
return mImpl.getFromSimpleChunk(ChunkType::MaterialCullingMode, reinterpret_cast<uint8_t*>(value));
return mImpl.getFromSimpleChunk(MaterialCullingMode, reinterpret_cast<uint8_t*>(value));
}
bool MaterialParser::getTransparencyMode(TransparencyMode* value) const noexcept {
static_assert(sizeof(TransparencyMode) == sizeof(uint8_t),
"TransparencyMode expected size is wrong");
return mImpl.getFromSimpleChunk(ChunkType::MaterialTransparencyMode,
return mImpl.getFromSimpleChunk(MaterialTransparencyMode,
reinterpret_cast<uint8_t*>(value));
}
bool MaterialParser::getInterpolation(Interpolation* value) const noexcept {
static_assert(sizeof(Interpolation) == sizeof(uint8_t),
"Interpolation expected size is wrong");
return mImpl.getFromSimpleChunk(ChunkType::MaterialInterpolation, reinterpret_cast<uint8_t*>(value));
return mImpl.getFromSimpleChunk(MaterialInterpolation, reinterpret_cast<uint8_t*>(value));
}
bool MaterialParser::getVertexDomain(VertexDomain* value) const noexcept {
static_assert(sizeof(VertexDomain) == sizeof(uint8_t),
"VertexDomain expected size is wrong");
return mImpl.getFromSimpleChunk(ChunkType::MaterialVertexDomain, reinterpret_cast<uint8_t*>(value));
return mImpl.getFromSimpleChunk(MaterialVertexDomain, reinterpret_cast<uint8_t*>(value));
}
bool MaterialParser::getMaterialVariantFilterMask(UserVariantFilterMask* value) const noexcept {
static_assert(sizeof(UserVariantFilterMask) == sizeof(uint32_t),
"UserVariantFilterMask expected size is wrong");
return mImpl.getFromSimpleChunk(ChunkType::MaterialVariantFilterMask,
return mImpl.getFromSimpleChunk(MaterialVariantFilterMask,
reinterpret_cast<UserVariantFilterMask*>(value));
}
@@ -304,12 +304,12 @@ bool MaterialParser::getMaterialDomain(MaterialDomain* value) const noexcept {
bool MaterialParser::getBlendingMode(BlendingMode* value) const noexcept {
static_assert(sizeof(BlendingMode) == sizeof(uint8_t),
"BlendingMode expected size is wrong");
return mImpl.getFromSimpleChunk(ChunkType::MaterialBlendingMode, reinterpret_cast<uint8_t*>(value));
return mImpl.getFromSimpleChunk(MaterialBlendingMode, reinterpret_cast<uint8_t*>(value));
}
bool MaterialParser::getCustomBlendFunction(std::array<BlendFunction, 4>* value) const noexcept {
uint32_t blendFunctions = 0;
bool const result = mImpl.getFromSimpleChunk(ChunkType::MaterialBlendFunction, &blendFunctions);
bool const result = mImpl.getFromSimpleChunk(MaterialBlendFunction, &blendFunctions);
(*value)[0] = BlendFunction((blendFunctions >> 24) & 0xFF);
(*value)[1] = BlendFunction((blendFunctions >> 16) & 0xFF);
(*value)[2] = BlendFunction((blendFunctions >> 8) & 0xFF);
@@ -318,52 +318,52 @@ bool MaterialParser::getCustomBlendFunction(std::array<BlendFunction, 4>* value)
}
bool MaterialParser::getMaskThreshold(float* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialMaskThreshold, value);
return mImpl.getFromSimpleChunk(MaterialMaskThreshold, value);
}
bool MaterialParser::getAlphaToCoverageSet(bool* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialAlphaToCoverageSet, value);
return mImpl.getFromSimpleChunk(MaterialAlphaToCoverageSet, value);
}
bool MaterialParser::getAlphaToCoverage(bool* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialAlphaToCoverage, value);
return mImpl.getFromSimpleChunk(MaterialAlphaToCoverage, value);
}
bool MaterialParser::hasShadowMultiplier(bool* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialShadowMultiplier, value);
return mImpl.getFromSimpleChunk(MaterialShadowMultiplier, value);
}
bool MaterialParser::getShading(Shading* value) const noexcept {
static_assert(sizeof(Shading) == sizeof(uint8_t),
"Shading expected size is wrong");
return mImpl.getFromSimpleChunk(ChunkType::MaterialShading, reinterpret_cast<uint8_t*>(value));
return mImpl.getFromSimpleChunk(MaterialShading, reinterpret_cast<uint8_t*>(value));
}
bool MaterialParser::hasCustomDepthShader(bool* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialHasCustomDepthShader, value);
return mImpl.getFromSimpleChunk(MaterialHasCustomDepthShader, value);
}
bool MaterialParser::hasSpecularAntiAliasing(bool* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialSpecularAntiAliasing, value);
return mImpl.getFromSimpleChunk(MaterialSpecularAntiAliasing, value);
}
bool MaterialParser::getSpecularAntiAliasingVariance(float* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialSpecularAntiAliasingVariance, value);
return mImpl.getFromSimpleChunk(MaterialSpecularAntiAliasingVariance, value);
}
bool MaterialParser::getSpecularAntiAliasingThreshold(float* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialSpecularAntiAliasingThreshold, value);
return mImpl.getFromSimpleChunk(MaterialSpecularAntiAliasingThreshold, value);
}
bool MaterialParser::getStereoscopicType(backend::StereoscopicType* value) const noexcept {
bool MaterialParser::getStereoscopicType(StereoscopicType* value) const noexcept {
static_assert(sizeof(StereoscopicType) == sizeof(uint8_t),
"StereoscopicType expected size is wrong");
return mImpl.getFromSimpleChunk(ChunkType::MaterialStereoscopicType, reinterpret_cast<uint8_t*>(value));
return mImpl.getFromSimpleChunk(MaterialStereoscopicType, reinterpret_cast<uint8_t*>(value));
}
bool MaterialParser::getRequiredAttributes(AttributeBitset* value) const noexcept {
uint32_t rawAttributes = 0;
if (!mImpl.getFromSimpleChunk(ChunkType::MaterialRequiredAttributes, &rawAttributes)) {
if (!mImpl.getFromSimpleChunk(MaterialRequiredAttributes, &rawAttributes)) {
return false;
}
*value = AttributeBitset();
@@ -374,23 +374,23 @@ bool MaterialParser::getRequiredAttributes(AttributeBitset* value) const noexcep
bool MaterialParser::getRefractionMode(RefractionMode* value) const noexcept {
static_assert(sizeof(RefractionMode) == sizeof(uint8_t),
"Refraction expected size is wrong");
return mImpl.getFromSimpleChunk(ChunkType::MaterialRefraction, (uint8_t*)value);
return mImpl.getFromSimpleChunk(MaterialRefraction, (uint8_t*)value);
}
bool MaterialParser::getRefractionType(RefractionType* value) const noexcept {
static_assert(sizeof(RefractionType) == sizeof(uint8_t),
"RefractionType expected size is wrong");
return mImpl.getFromSimpleChunk(ChunkType::MaterialRefractionType, (uint8_t*)value);
return mImpl.getFromSimpleChunk(MaterialRefractionType, (uint8_t*)value);
}
bool MaterialParser::getReflectionMode(ReflectionMode* value) const noexcept {
static_assert(sizeof(ReflectionMode) == sizeof(uint8_t),
"ReflectionMode expected size is wrong");
return mImpl.getFromSimpleChunk(ChunkType::MaterialReflectionMode, (uint8_t*)value);
return mImpl.getFromSimpleChunk(MaterialReflectionMode, (uint8_t*)value);
}
bool MaterialParser::getShader(ShaderContent& shader,
ShaderModel shaderModel, Variant variant, ShaderStage stage) noexcept {
ShaderModel const shaderModel, Variant const variant, ShaderStage const stage) noexcept {
return mImpl.mMaterialChunk.getShader(shader,
mImpl.mBlobDictionary, shaderModel, variant, stage);
}
@@ -399,7 +399,7 @@ bool MaterialParser::getShader(ShaderContent& shader,
bool ChunkUniformInterfaceBlock::unflatten(Unflattener& unflattener,
filament::BufferInterfaceBlock* uib) {
BufferInterfaceBlock* uib) {
BufferInterfaceBlock::Builder builder = BufferInterfaceBlock::Builder();
@@ -450,7 +450,7 @@ bool ChunkUniformInterfaceBlock::unflatten(Unflattener& unflattener,
}
bool ChunkSamplerInterfaceBlock::unflatten(Unflattener& unflattener,
filament::SamplerInterfaceBlock* sib) {
SamplerInterfaceBlock* sib) {
SamplerInterfaceBlock::Builder builder = SamplerInterfaceBlock::Builder();
@@ -467,7 +467,7 @@ bool ChunkSamplerInterfaceBlock::unflatten(Unflattener& unflattener,
}
for (uint64_t i = 0; i < numFields; i++) {
static_assert(sizeof(backend::descriptor_binding_t) == sizeof(uint8_t));
static_assert(sizeof(descriptor_binding_t) == sizeof(uint8_t));
CString fieldName;
uint8_t fieldBinding = 0;
uint8_t fieldType = 0;
@@ -512,7 +512,7 @@ bool ChunkSamplerInterfaceBlock::unflatten(Unflattener& unflattener,
}
bool ChunkSubpassInterfaceBlock::unflatten(Unflattener& unflattener,
filament::SubpassInfo* subpass) {
SubpassInfo* subpass) {
CString block;
if (!unflattener.read(&block)) {
@@ -566,7 +566,7 @@ bool ChunkSubpassInterfaceBlock::unflatten(Unflattener& unflattener,
return true;
}
bool ChunkBindingUniformInfo::unflatten(filaflat::Unflattener& unflattener,
bool ChunkBindingUniformInfo::unflatten(Unflattener& unflattener,
MaterialParser::BindingUniformInfoContainer* bindingUniformInfo) {
uint8_t bindingPointCount;
if (!unflattener.read(&bindingPointCount)) {
@@ -578,7 +578,7 @@ bool ChunkBindingUniformInfo::unflatten(filaflat::Unflattener& unflattener,
if (!unflattener.read(&index)) {
return false;
}
utils::CString uboName;
CString uboName;
if (!unflattener.read(&uboName)) {
return false;
}
@@ -589,7 +589,7 @@ bool ChunkBindingUniformInfo::unflatten(filaflat::Unflattener& unflattener,
Program::UniformInfo uniforms = Program::UniformInfo::with_capacity(uniformCount);
for (size_t j = 0; j < uniformCount; j++) {
utils::CString name;
CString name;
if (!unflattener.read(&name)) {
return false;
}
@@ -612,7 +612,7 @@ bool ChunkBindingUniformInfo::unflatten(filaflat::Unflattener& unflattener,
return true;
}
bool ChunkAttributeInfo::unflatten(filaflat::Unflattener& unflattener,
bool ChunkAttributeInfo::unflatten(Unflattener& unflattener,
MaterialParser::AttributeInfoContainer* attributeInfoContainer) {
uint8_t attributeCount;
@@ -623,7 +623,7 @@ bool ChunkAttributeInfo::unflatten(filaflat::Unflattener& unflattener,
attributeInfoContainer->reserve(attributeCount);
for (size_t j = 0; j < attributeCount; j++) {
utils::CString name;
CString name;
if (!unflattener.read(&name)) {
return false;
}
@@ -637,7 +637,7 @@ bool ChunkAttributeInfo::unflatten(filaflat::Unflattener& unflattener,
return true;
}
bool ChunkDescriptorBindingsInfo::unflatten(filaflat::Unflattener& unflattener,
bool ChunkDescriptorBindingsInfo::unflatten(Unflattener& unflattener,
MaterialParser::DescriptorBindingsContainer* container) {
uint8_t setCount;
@@ -661,7 +661,7 @@ bool ChunkDescriptorBindingsInfo::unflatten(filaflat::Unflattener& unflattener,
auto& descriptors = (*container)[+set];
descriptors.reserve(descriptorCount);
for (size_t i = 0; i < descriptorCount; i++) {
utils::CString name;
CString name;
if (!unflattener.read(&name)) {
return false;
}
@@ -675,15 +675,15 @@ bool ChunkDescriptorBindingsInfo::unflatten(filaflat::Unflattener& unflattener,
}
descriptors.push_back({
std::move(name),
backend::DescriptorType(type),
backend::descriptor_binding_t(binding)});
DescriptorType(type),
descriptor_binding_t(binding)});
}
}
return true;
}
bool ChunkDescriptorSetLayoutInfo::unflatten(filaflat::Unflattener& unflattener,
bool ChunkDescriptorSetLayoutInfo::unflatten(Unflattener& unflattener,
MaterialParser::DescriptorSetLayoutContainer* container) {
for (size_t j = 0; j < 2; j++) {
uint8_t descriptorCount;
@@ -714,10 +714,10 @@ bool ChunkDescriptorSetLayoutInfo::unflatten(filaflat::Unflattener& unflattener,
return false;
}
descriptors.push_back({
backend::DescriptorType(type),
backend::ShaderStageFlags(stageFlags),
backend::descriptor_binding_t(binding),
backend::DescriptorFlags(flags),
DescriptorType(type),
ShaderStageFlags(stageFlags),
descriptor_binding_t(binding),
DescriptorFlags(flags),
count,
});
}
@@ -725,8 +725,8 @@ bool ChunkDescriptorSetLayoutInfo::unflatten(filaflat::Unflattener& unflattener,
return true;
}
bool ChunkMaterialConstants::unflatten(filaflat::Unflattener& unflattener,
utils::FixedCapacityVector<MaterialConstant>* materialConstants) {
bool ChunkMaterialConstants::unflatten(Unflattener& unflattener,
FixedCapacityVector<MaterialConstant>* materialConstants) {
assert_invariant(materialConstants);
// Read number of constants.
@@ -751,15 +751,15 @@ bool ChunkMaterialConstants::unflatten(filaflat::Unflattener& unflattener,
}
(*materialConstants)[i].name = constantName;
(*materialConstants)[i].type = static_cast<backend::ConstantType>(constantType);
(*materialConstants)[i].type = static_cast<ConstantType>(constantType);
}
return true;
}
bool ChunkMaterialPushConstants::unflatten(filaflat::Unflattener& unflattener,
utils::CString* structVarName,
utils::FixedCapacityVector<MaterialPushConstant>* materialPushConstants) {
bool ChunkMaterialPushConstants::unflatten(Unflattener& unflattener,
CString* structVarName,
FixedCapacityVector<MaterialPushConstant>* materialPushConstants) {
assert_invariant(materialPushConstants);
if (!unflattener.read(structVarName)) {
@@ -793,8 +793,8 @@ bool ChunkMaterialPushConstants::unflatten(filaflat::Unflattener& unflattener,
}
(*materialPushConstants)[i].name = constantName;
(*materialPushConstants)[i].type = static_cast<backend::ConstantType>(constantType);
(*materialPushConstants)[i].stage = static_cast<backend::ShaderStage>(shaderStage);
(*materialPushConstants)[i].type = static_cast<ConstantType>(constantType);
(*materialPushConstants)[i].stage = static_cast<ShaderStage>(shaderStage);
}
return true;
}
+2 -2
View File
@@ -130,8 +130,8 @@ public:
bool getShader(filaflat::ShaderContent& shader, backend::ShaderModel shaderModel,
Variant variant, backend::ShaderStage stage) noexcept;
bool hasShader(backend::ShaderModel model,
Variant variant, backend::ShaderStage stage) const noexcept {
bool hasShader(backend::ShaderModel const model,
Variant const variant, backend::ShaderStage const stage) const noexcept {
return getMaterialChunk().hasShader(model, variant, stage);
}
+6 -6
View File
@@ -20,18 +20,18 @@
namespace filament {
void MorphTargetBuffer::setPositionsAt(Engine& engine, size_t targetIndex,
math::float3 const* positions, size_t count, size_t offset) {
void MorphTargetBuffer::setPositionsAt(Engine& engine, size_t const targetIndex,
math::float3 const* positions, size_t const count, size_t const offset) {
downcast(this)->setPositionsAt(downcast(engine), targetIndex, positions, count, offset);
}
void MorphTargetBuffer::setPositionsAt(Engine& engine, size_t targetIndex,
math::float4 const* positions, size_t count, size_t offset) {
void MorphTargetBuffer::setPositionsAt(Engine& engine, size_t const targetIndex,
math::float4 const* positions, size_t const count, size_t const offset) {
downcast(this)->setPositionsAt(downcast(engine), targetIndex, positions, count, offset);
}
void MorphTargetBuffer::setTangentsAt(Engine& engine, size_t targetIndex,
math::short4 const* tangents, size_t count, size_t offset) {
void MorphTargetBuffer::setTangentsAt(Engine& engine, size_t const targetIndex,
math::short4 const* tangents, size_t const count, size_t const offset) {
downcast(this)->setTangentsAt(downcast(engine), targetIndex, tangents, count, offset);
}
+7 -7
View File
@@ -27,43 +27,43 @@ class PIDController {
public:
PIDController() noexcept = default;
void setStandardGains(float Kp, float Ti, float Td) noexcept {
void setStandardGains(float const Kp, float const Ti, float const Td) noexcept {
mKp = Kp;
mKi = Kp / Ti;
mKd = Kp * Td;
}
void setParallelGains(float Kp, float Ki, float Kd) noexcept {
void setParallelGains(float const Kp, float const Ki, float const Kd) noexcept {
mKp = Kp;
mKi = Ki;
mKd = Kd;
}
// output is kept steady in the dead band
void setOutputDeadBand(float low, float high) noexcept {
void setOutputDeadBand(float const low, float const high) noexcept {
mDeadBandLow = low;
mDeadBandHigh = high;
}
// integral bounds to prevent windup
void setIntegralLimits(float low, float high) noexcept {
void setIntegralLimits(float const low, float const high) noexcept {
mIntegralLimitLow = low;
mIntegralLimitHigh = high;
}
// output bounds
void setOutputLimits(float low, float high) noexcept {
void setOutputLimits(float const low, float const high) noexcept {
mOutputLimitLow = low;
mOutputLimitHigh = high;
}
// disable integral term to prevent windup
void setIntegralInhibitionEnabled(bool enabled) noexcept {
void setIntegralInhibitionEnabled(bool const enabled) noexcept {
mIntegralInhibition = enabled ? 0.0f : 1.0f;
}
// update PID output
float update(float measure, float target, float dt) const noexcept {
float update(float const measure, float const target, float const dt) const noexcept {
// compute error
const float error = target - measure;
File diff suppressed because it is too large Load Diff
+25 -12
View File
@@ -89,7 +89,7 @@ public:
bool asSubpass{};
bool customResolve{};
bool translucent{};
bool fxaa{};
bool outputLuminance{}; // Whether to output luminance in the alpha channel. Ignored by the TRANSLUCENT variant.
bool dithering{};
backend::TextureFormat ldrFormat{};
};
@@ -130,8 +130,8 @@ public:
// SSAO
FrameGraphId<FrameGraphTexture> screenSpaceAmbientOcclusion(FrameGraph& fg,
filament::Viewport const& svp, const CameraInfo& cameraInfo,
FrameGraphId<FrameGraphTexture> structure,
Viewport const& svp, const CameraInfo& cameraInfo,
FrameGraphId<FrameGraphTexture> depth,
AmbientOcclusionOptions const& options) noexcept;
// Gaussian mipmap
@@ -201,7 +201,7 @@ public:
// Color grading, tone mapping, dithering and bloom
FrameGraphId<FrameGraphTexture> colorGrading(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> input, filament::Viewport const& vp,
FrameGraphId<FrameGraphTexture> input, Viewport const& vp,
FrameGraphId<FrameGraphTexture> bloom,
FrameGraphId<FrameGraphTexture> flare,
const FColorGrading* colorGrading,
@@ -226,12 +226,12 @@ public:
// Anti-aliasing
FrameGraphId<FrameGraphTexture> fxaa(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> input, filament::Viewport const& vp,
backend::TextureFormat outFormat, bool translucent) noexcept;
FrameGraphId<FrameGraphTexture> input, Viewport const& vp,
backend::TextureFormat outFormat, bool preserveAlphaChannel) noexcept;
// Temporal Anti-aliasing
void TaaJitterCamera(
filament::Viewport const& svp,
Viewport const& svp,
TemporalAntiAliasingOptions const& taaOptions,
FrameHistory& frameHistory,
FrameHistoryEntry::TemporalAA FrameHistoryEntry::*pTaa,
@@ -251,12 +251,25 @@ public:
// high quality upscaler
// - when translucent, reverts to LINEAR
// - doens't handle sub-resouces
// - doesn't handle sub-resouces
FrameGraphId<FrameGraphTexture> upscale(FrameGraph& fg, bool translucent,
bool sourceHasLuminance, DynamicResolutionOptions dsrOptions,
FrameGraphId<FrameGraphTexture> input, Viewport const& vp,
FrameGraphTexture::Descriptor const& outDesc, backend::SamplerMagFilter filter) noexcept;
FrameGraphId<FrameGraphTexture> upscaleBilinear(FrameGraph& fg, bool translucent,
DynamicResolutionOptions dsrOptions, FrameGraphId<FrameGraphTexture> input,
filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc,
Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc,
backend::SamplerMagFilter filter) noexcept;
FrameGraphId<FrameGraphTexture> upscaleFSR1(FrameGraph& fg,
DynamicResolutionOptions dsrOptions, FrameGraphId<FrameGraphTexture> input,
filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc) noexcept;
FrameGraphId<FrameGraphTexture> upscaleSGSR1(FrameGraph& fg, bool sourceHasLuminance,
DynamicResolutionOptions dsrOptions, FrameGraphId<FrameGraphTexture> input,
filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc) noexcept;
FrameGraphId<FrameGraphTexture> rcas(
FrameGraph& fg,
float sharpness,
@@ -267,7 +280,7 @@ public:
// color blitter using shaders
FrameGraphId<FrameGraphTexture> blit(FrameGraph& fg, bool translucent,
FrameGraphId<FrameGraphTexture> input,
filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc,
Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc,
backend::SamplerMagFilter filterMag,
backend::SamplerMinFilter filterMin) noexcept;
@@ -311,7 +324,7 @@ public:
// is not expected to be used in normal cases.
FrameGraphId<FrameGraphTexture> debugCombineArrayTexture(FrameGraph& fg, bool translucent,
FrameGraphId<FrameGraphTexture> input,
filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc,
Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc,
backend::SamplerMagFilter filterMag,
backend::SamplerMinFilter filterMin) noexcept;
@@ -428,7 +441,7 @@ private:
template<size_t SIZE>
struct JitterSequence {
math::float2 operator()(size_t i) const noexcept { return positions[i % SIZE] - 0.5f; }
math::float2 operator()(size_t const i) const noexcept { return positions[i % SIZE] - 0.5f; }
const std::array<math::float2, SIZE> positions;
};
+48 -39
View File
@@ -26,8 +26,6 @@
#include "components/RenderableManager.h"
#include "ds/DescriptorSet.h"
#include <private/filament/EngineEnums.h>
#include <private/filament/UibStructs.h>
#include <private/filament/Variant.h>
@@ -81,7 +79,7 @@ RenderPassBuilder& RenderPassBuilder::customCommand(
return *this;
}
RenderPass RenderPassBuilder::build(FEngine const& engine, backend::DriverApi& driver) const {
RenderPass RenderPassBuilder::build(FEngine const& engine, DriverApi& driver) const {
assert_invariant(mRenderableSoa);
assert_invariant(mScissorViewport.width <= std::numeric_limits<int32_t>::max());
assert_invariant(mScissorViewport.height <= std::numeric_limits<int32_t>::max());
@@ -90,15 +88,14 @@ RenderPass RenderPassBuilder::build(FEngine const& engine, backend::DriverApi& d
// ------------------------------------------------------------------------------------------------
void RenderPass::BufferObjectHandleDeleter::operator()(
backend::BufferObjectHandle handle) noexcept {
void RenderPass::BufferObjectHandleDeleter::operator()(BufferObjectHandle handle) noexcept {
if (handle) { // this is common case
driver.get().destroyBufferObject(handle);
}
}
void RenderPass::DescriptorSetHandleDeleter::operator()(
backend::DescriptorSetHandle handle) noexcept {
DescriptorSetHandle handle) noexcept {
if (handle) { // this is common case
driver.get().destroyDescriptorSet(handle);
}
@@ -106,7 +103,7 @@ void RenderPass::DescriptorSetHandleDeleter::operator()(
// ------------------------------------------------------------------------------------------------
RenderPass::RenderPass(FEngine const& engine, backend::DriverApi& driver,
RenderPass::RenderPass(FEngine const& engine, DriverApi& driver,
RenderPassBuilder const& builder) noexcept
: mRenderableSoa(*builder.mRenderableSoa),
mColorPassDescriptorSet(builder.mColorPassDescriptorSet),
@@ -160,7 +157,7 @@ RenderPass::RenderPass(FEngine const& engine, backend::DriverApi& driver,
// sort commands once we're done adding commands
commandEnd = resize(builder.mArena,
RenderPass::sortCommands(commandBegin, commandEnd));
sortCommands(commandBegin, commandEnd));
if (engine.isAutomaticInstancingEnabled()) {
int32_t stereoscopicEyeCount = 1;
@@ -188,19 +185,19 @@ RenderPass::Command* RenderPass::resize(Arena& arena, Command* const last) noexc
void RenderPass::appendCommands(FEngine const& engine,
Slice<Command> commands,
utils::Range<uint32_t> const vr,
Range<uint32_t> const visibleRenderables,
CommandTypeFlags const commandTypeFlags,
RenderFlags const renderFlags,
FScene::VisibleMaskType const visibilityMask,
Variant const variant,
float3 const cameraPosition,
float3 const cameraForwardVector) noexcept {
float3 const cameraForwardVector) const noexcept {
SYSTRACE_CALL();
SYSTRACE_CONTEXT();
// trace the number of visible renderables
SYSTRACE_VALUE32("visibleRenderables", vr.size());
if (UTILS_UNLIKELY(vr.empty())) {
SYSTRACE_VALUE32("visibleRenderables", visibleRenderables.size());
if (UTILS_UNLIKELY(visibleRenderables.empty())) {
// no renderables, we still need the sentinel and the command buffer size should be
// exactly 1.
assert_invariant(commands.size() == 1);
@@ -222,17 +219,18 @@ void RenderPass::appendCommands(FEngine const& engine,
auto work = [commandTypeFlags, curr, &soa,
variant, renderFlags, visibilityMask,
cameraPosition, cameraForwardVector, stereoscopicEyeCount]
(uint32_t startIndex, uint32_t indexCount) {
RenderPass::generateCommands(commandTypeFlags, curr,
(uint32_t const startIndex, uint32_t const indexCount) {
generateCommands(commandTypeFlags, curr,
soa, { startIndex, startIndex + indexCount },
variant, renderFlags, visibilityMask,
cameraPosition, cameraForwardVector, stereoscopicEyeCount);
};
if (vr.size() <= JOBS_PARALLEL_FOR_COMMANDS_COUNT) {
work(vr.first, vr.size());
if (visibleRenderables.size() <= JOBS_PARALLEL_FOR_COMMANDS_COUNT) {
work(visibleRenderables.first, visibleRenderables.size());
} else {
auto* jobCommandsParallel = jobs::parallel_for(js, nullptr, vr.first, (uint32_t)vr.size(),
auto* jobCommandsParallel = parallel_for(js, nullptr,
visibleRenderables.first, uint32_t(visibleRenderables.size()),
std::cref(work), jobs::CountSplitter<JOBS_PARALLEL_FOR_COMMANDS_COUNT>());
js.runAndWait(jobCommandsParallel);
}
@@ -253,7 +251,7 @@ void RenderPass::appendCommands(FEngine const& engine,
}
void RenderPass::appendCustomCommand(Command* commands,
uint8_t channel, Pass pass, CustomCommand custom, uint32_t order,
uint8_t channel, Pass pass, CustomCommand custom, uint32_t const order,
Executor::CustomCommandFn command) {
assert_invariant((uint64_t(order) << CUSTOM_ORDER_SHIFT) <= CUSTOM_ORDER_MASK);
@@ -287,10 +285,10 @@ RenderPass::Command* RenderPass::sortCommands(
return last;
}
RenderPass::Command* RenderPass::instanceify(backend::DriverApi& driver,
RenderPass::Command* RenderPass::instanceify(DriverApi& driver,
DescriptorSetLayoutHandle perRenderableDescriptorSetLayoutHandle,
Command* curr, Command* const last,
int32_t eyeCount) const noexcept {
int32_t const eyeCount) const noexcept {
SYSTRACE_NAME("instanceify");
// instanceify works by scanning the **sorted** command stream, looking for repeat draw
@@ -365,7 +363,7 @@ RenderPass::Command* RenderPass::instanceify(backend::DriverApi& driver,
// TODO: use a pool for larger heap buffers
// buffer large enough for all instances data
stagingBufferSize = count * sizeof(PerRenderableData);
stagingBuffer = (PerRenderableData*)::malloc(stagingBufferSize);
stagingBuffer = static_cast<PerRenderableData*>(malloc(stagingBufferSize));
uboData = mRenderableSoa.data<FScene::UBO>();
assert_invariant(uboData);
@@ -415,14 +413,14 @@ RenderPass::Command* RenderPass::instanceify(backend::DriverApi& driver,
driver.updateBufferObjectUnsynchronized(mInstancedUboHandle, {
stagingBuffer, sizeof(PerRenderableData) * instancedPrimitiveOffset,
+[](void* buffer, size_t, void*) {
::free(buffer);
free(buffer);
}
}, 0);
stagingBuffer = nullptr;
// remove all the canceled commands
auto lastCommand = std::remove_if(firstSentinel, last, [](auto const& command) {
auto const lastCommand = std::remove_if(firstSentinel, last, [](auto const& command) {
return command.key == uint64_t(Pass::SENTINEL);
});
@@ -439,7 +437,7 @@ UTILS_ALWAYS_INLINE // This function exists only to make the code more readable.
inline // and we don't need it in the compilation unit
void RenderPass::setupColorCommand(Command& cmdDraw, Variant variant,
FMaterialInstance const* const UTILS_RESTRICT mi,
bool inverseFrontFaces, bool hasDepthClamp) noexcept {
bool const inverseFrontFaces, bool const hasDepthClamp) noexcept {
FMaterial const * const UTILS_RESTRICT ma = mi->getMaterial();
variant = Variant::filterVariant(variant, ma->isVariantLit());
@@ -492,7 +490,7 @@ void RenderPass::generateCommands(CommandTypeFlags commandTypeFlags, Command* co
Variant const variant, RenderFlags const renderFlags,
FScene::VisibleMaskType const visibilityMask,
float3 const cameraPosition, float3 const cameraForward,
uint8_t stereoEyeCount) noexcept {
uint8_t instancedStereoEyeCount) noexcept {
SYSTRACE_CALL();
@@ -525,13 +523,13 @@ void RenderPass::generateCommands(CommandTypeFlags commandTypeFlags, Command* co
curr = generateCommandsImpl<CommandTypeFlags::COLOR>(commandTypeFlags, curr,
soa, range,
variant, renderFlags, visibilityMask, cameraPosition, cameraForward,
stereoEyeCount);
instancedStereoEyeCount);
break;
case CommandTypeFlags::DEPTH:
curr = generateCommandsImpl<CommandTypeFlags::DEPTH>(commandTypeFlags, curr,
soa, range,
variant, renderFlags, visibilityMask, cameraPosition, cameraForward,
stereoEyeCount);
instancedStereoEyeCount);
break;
default:
// we should never end-up here
@@ -550,11 +548,11 @@ void RenderPass::generateCommands(CommandTypeFlags commandTypeFlags, Command* co
/* static */
template<RenderPass::CommandTypeFlags commandTypeFlags>
UTILS_NOINLINE
RenderPass::Command* RenderPass::generateCommandsImpl(RenderPass::CommandTypeFlags extraFlags,
RenderPass::Command* RenderPass::generateCommandsImpl(CommandTypeFlags extraFlags,
Command* UTILS_RESTRICT curr,
FScene::RenderableSoa const& UTILS_RESTRICT soa, Range<uint32_t> range,
Variant const variant, RenderFlags renderFlags, FScene::VisibleMaskType visibilityMask,
float3 cameraPosition, float3 cameraForward, uint8_t stereoEyeCount) noexcept {
float3 cameraPosition, float3 cameraForward, uint8_t instancedStereoEyeCount) noexcept {
constexpr bool isColorPass = bool(commandTypeFlags & CommandTypeFlags::COLOR);
constexpr bool isDepthPass = bool(commandTypeFlags & CommandTypeFlags::DEPTH);
@@ -675,16 +673,16 @@ RenderPass::Command* RenderPass::generateCommandsImpl(RenderPass::CommandTypeFla
cmd.key |= makeField(soaVisibility[i].priority, PRIORITY_MASK, PRIORITY_SHIFT);
cmd.key |= makeField(soaVisibility[i].channel, CHANNEL_MASK, CHANNEL_SHIFT);
cmd.info.index = i;
cmd.info.hasHybridInstancing = (bool)soaInstanceInfo[i].handle;
cmd.info.hasHybridInstancing = bool(soaInstanceInfo[i].handle);
cmd.info.instanceCount = soaInstanceInfo[i].count;
cmd.info.hasMorphing = (bool)morphing.handle;
cmd.info.hasSkinning = (bool)skinning.handle;
cmd.info.hasMorphing = bool(morphing.handle);
cmd.info.hasSkinning = bool(skinning.handle);
// soaInstanceInfo[i].count is the number of instances the user has requested, either for
// manual or hybrid instancing. Instanced stereo multiplies the number of instances by the
// eye count.
if (hasInstancedStereo) {
cmd.info.instanceCount *= stereoEyeCount;
cmd.info.instanceCount *= instancedStereoEyeCount;
}
// soaDescriptorSet[i] is either populated with a common descriptor-set or truly with
@@ -704,11 +702,22 @@ RenderPass::Command* RenderPass::generateCommandsImpl(RenderPass::CommandTypeFla
*/
for (auto const& primitive: primitives) {
FMaterialInstance const* const mi = primitive.getMaterialInstance();
FMaterial const* const ma = mi->getMaterial();
if (UTILS_UNLIKELY(!mi)) {
// This can happen because RenderPrimitives can be initialized with
// a null MaterialInstance. In this case, skip the primitive.
if constexpr (isColorPass) {
curr->key = uint64_t(Pass::SENTINEL);
++curr;
}
curr->key = uint64_t(Pass::SENTINEL);
++curr;
continue;
}
// TODO: we should disable the SKN variant if this primitive doesn't have either
// skinning or morphing.
FMaterial const* const ma = mi->getMaterial();
cmd.info.mi = mi;
cmd.info.rph = primitive.getHwHandle();
cmd.info.vbih = primitive.getVertexBufferInfoHandle();
@@ -721,7 +730,7 @@ RenderPass::Command* RenderPass::generateCommandsImpl(RenderPass::CommandTypeFla
// morphing.morphTargetBuffer->getHwHandle() : SamplerGroupHandle{};
if constexpr (isColorPass) {
RenderPass::setupColorCommand(cmd, renderableVariant, mi,
setupColorCommand(cmd, renderableVariant, mi,
inverseFrontFaces, hasDepthClamp);
const bool blendPass = Pass(cmd.key & PASS_MASK) == Pass::BLENDED;
if (blendPass) {
@@ -842,7 +851,7 @@ void RenderPass::updateSummedPrimitiveCounts(
// ------------------------------------------------------------------------------------------------
void RenderPass::Executor::overridePolygonOffset(backend::PolygonOffset const* polygonOffset) noexcept {
void RenderPass::Executor::overridePolygonOffset(PolygonOffset const* polygonOffset) noexcept {
if ((mPolygonOffsetOverride = (polygonOffset != nullptr))) { // NOLINT(*-assignment-in-if-condition)
mPolygonOffset = *polygonOffset;
}
@@ -853,7 +862,7 @@ void RenderPass::Executor::overrideScissor(backend::Viewport const& scissor) noe
mScissor = scissor;
}
void RenderPass::Executor::execute(FEngine const& engine, backend::DriverApi& driver) const noexcept {
void RenderPass::Executor::execute(FEngine const& engine, DriverApi& driver) const noexcept {
execute(engine, driver, mCommands.begin(), mCommands.end());
}
@@ -903,7 +912,7 @@ backend::Viewport RenderPass::Executor::applyScissorViewport(
}
UTILS_NOINLINE // no need to be inlined
void RenderPass::Executor::execute(FEngine const& engine, backend::DriverApi& driver,
void RenderPass::Executor::execute(FEngine const& engine, DriverApi& driver,
Command const* first, Command const* last) const noexcept {
SYSTRACE_CALL();
@@ -947,7 +956,7 @@ void RenderPass::Executor::execute(FEngine const& engine, backend::DriverApi& dr
// CommandStream protocol. Currently, the maximum is 248 bytes.
// The batch size is calculated by adding the size of all commands that can possibly be
// emitted per draw call:
constexpr size_t const maxCommandSizeInBytes =
constexpr size_t maxCommandSizeInBytes =
sizeof(COMMAND_TYPE(scissor)) +
sizeof(COMMAND_TYPE(bindDescriptorSet)) +
sizeof(COMMAND_TYPE(bindDescriptorSet)) +
+14 -14
View File
@@ -219,14 +219,14 @@ public:
*
* The variant is inserted while building the commands, because we don't know it before that
*/
static CommandKey makeMaterialSortingKey(uint32_t materialId, uint32_t instanceId) noexcept {
static CommandKey makeMaterialSortingKey(uint32_t const materialId, uint32_t const instanceId) noexcept {
CommandKey const key = ((materialId << MATERIAL_ID_SHIFT) & MATERIAL_ID_MASK) |
((instanceId << MATERIAL_INSTANCE_ID_SHIFT) & MATERIAL_INSTANCE_ID_MASK);
return (key << MATERIAL_SHIFT) & MATERIAL_MASK;
}
template<typename T>
static CommandKey makeField(T value, uint64_t mask, unsigned shift) noexcept {
static CommandKey makeField(T value, uint64_t const mask, unsigned const shift) noexcept {
assert_invariant(!((uint64_t(value) << shift) & ~mask));
return uint64_t(value) << shift;
}
@@ -273,7 +273,7 @@ public:
PrimitiveInfo info; // 56 bytes
bool operator < (Command const& rhs) const noexcept { return key < rhs.key; }
// placement new declared as "throw" to avoid the compiler's null-check
inline void* operator new (size_t, void* ptr) {
void* operator new (size_t, void* ptr) {
assert_invariant(ptr);
return ptr;
}
@@ -412,7 +412,7 @@ private:
FScene::VisibleMaskType visibilityMask,
Variant variant,
math::float3 cameraPosition,
math::float3 cameraForwardVector) noexcept;
math::float3 cameraForwardVector) const noexcept;
// Appends a custom command.
void appendCustomCommand(Command* commands,
@@ -426,7 +426,7 @@ private:
Command* begin, Command* end) noexcept;
// instanceify commands then trims sentinels
RenderPass::Command* instanceify(backend::DriverApi& driver,
Command* instanceify(backend::DriverApi& driver,
backend::DescriptorSetLayoutHandle perRenderableDescriptorSetLayoutHandle,
Command* begin, Command* end,
int32_t eyeCount) const noexcept;
@@ -446,8 +446,8 @@ private:
math::float3 cameraPosition, math::float3 cameraForward,
uint8_t instancedStereoEyeCount) noexcept;
template<RenderPass::CommandTypeFlags commandTypeFlags>
static inline RenderPass::Command* generateCommandsImpl(RenderPass::CommandTypeFlags extraFlags,
template<CommandTypeFlags commandTypeFlags>
static Command* generateCommandsImpl(CommandTypeFlags extraFlags,
Command* curr, FScene::RenderableSoa const& soa, utils::Range<uint32_t> range,
Variant variant, RenderFlags renderFlags, FScene::VisibleMaskType visibilityMask,
math::float3 cameraPosition, math::float3 cameraForward,
@@ -502,21 +502,21 @@ class RenderPassBuilder {
public:
explicit RenderPassBuilder(RenderPass::Arena& arena) : mArena(arena) { }
RenderPassBuilder& commandTypeFlags(RenderPass::CommandTypeFlags commandTypeFlags) noexcept {
RenderPassBuilder& commandTypeFlags(RenderPass::CommandTypeFlags const commandTypeFlags) noexcept {
mCommandTypeFlags = commandTypeFlags;
return *this;
}
// Specifies the viewport for the scissor rectangle, that is, the final scissor rect is
// offset by the viewport's left-top and clipped to the viewport's width/height.
RenderPassBuilder& scissorViewport(backend::Viewport viewport) noexcept {
RenderPassBuilder& scissorViewport(backend::Viewport const viewport) noexcept {
mScissorViewport = viewport;
return *this;
}
// specifies the geometry to generate commands for
RenderPassBuilder& geometry(
FScene::RenderableSoa const& soa, utils::Range<uint32_t> vr) noexcept {
FScene::RenderableSoa const& soa, utils::Range<uint32_t> const vr) noexcept {
mRenderableSoa = &soa;
mVisibleRenderables = vr;
return *this;
@@ -530,14 +530,14 @@ public:
}
// flags controlling how commands are generated
RenderPassBuilder& renderFlags(RenderPass::RenderFlags flags) noexcept {
RenderPassBuilder& renderFlags(RenderPass::RenderFlags const flags) noexcept {
mFlags = flags;
return *this;
}
// like above but allows to set specific flags
RenderPassBuilder& renderFlags(
RenderPass::RenderFlags mask, RenderPass::RenderFlags value) noexcept {
RenderPass::RenderFlags const mask, RenderPass::RenderFlags value) noexcept {
value &= mask;
mFlags &= ~mask;
mFlags |= value;
@@ -545,7 +545,7 @@ public:
}
// variant to use
RenderPassBuilder& variant(Variant variant) noexcept {
RenderPassBuilder& variant(Variant const variant) noexcept {
mVariant = variant;
return *this;
}
@@ -559,7 +559,7 @@ public:
// Sets the visibility mask, which is AND-ed against each Renderable's VISIBLE_MASK to
// determine if the renderable is visible for this pass.
// Defaults to all 1's, which means all renderables in this render pass will be rendered.
RenderPassBuilder& visibilityMask(FScene::VisibleMaskType mask) noexcept {
RenderPassBuilder& visibilityMask(FScene::VisibleMaskType const mask) noexcept {
mVisibilityMask = mask;
return *this;
}
+5 -5
View File
@@ -41,8 +41,8 @@ void FRenderPrimitive::init(HwRenderPrimitiveFactory& factory, backend::DriverAp
mBlendOrder = entry.blendOrder;
if (entry.indices && entry.vertices) {
FVertexBuffer* vertexBuffer = downcast(entry.vertices);
FIndexBuffer* indexBuffer = downcast(entry.indices);
FVertexBuffer const* vertexBuffer = downcast(entry.vertices);
FIndexBuffer const* indexBuffer = downcast(entry.indices);
set(factory, driver, entry.type, vertexBuffer, indexBuffer, entry.offset, entry.count);
}
}
@@ -54,9 +54,9 @@ void FRenderPrimitive::terminate(HwRenderPrimitiveFactory& factory, backend::Dri
}
void FRenderPrimitive::set(HwRenderPrimitiveFactory& factory, backend::DriverApi& driver,
RenderableManager::PrimitiveType type,
FVertexBuffer* vertexBuffer, FIndexBuffer* indexBuffer,
size_t offset, size_t count) noexcept {
RenderableManager::PrimitiveType const type,
FVertexBuffer const* vertexBuffer, FIndexBuffer const* indexBuffer,
size_t const offset, size_t const count) noexcept {
if (mHandle) {
factory.destroy(driver, mHandle);
}
+4 -4
View File
@@ -45,7 +45,7 @@ public:
void set(HwRenderPrimitiveFactory& factory, backend::DriverApi& driver,
RenderableManager::PrimitiveType type,
FVertexBuffer* vertexBuffer, FIndexBuffer* indexBuffer, size_t offset,
FVertexBuffer const* vertexBuffer, FIndexBuffer const* indexBuffer, size_t offset,
size_t count) noexcept;
// frees driver resources, object becomes invalid
@@ -65,15 +65,15 @@ public:
void setMaterialInstance(FMaterialInstance const* mi) noexcept { mMaterialInstance = mi; }
void setBlendOrder(uint16_t order) noexcept {
void setBlendOrder(uint16_t const order) noexcept {
mBlendOrder = static_cast<uint16_t>(order & 0x7FFF);
}
void setGlobalBlendOrderEnabled(bool enabled) noexcept {
void setGlobalBlendOrderEnabled(bool const enabled) noexcept {
mGlobalBlendOrderEnabled = enabled;
}
void setMorphingBufferOffset(uint32_t offset) noexcept {
void setMorphingBufferOffset(uint32_t const offset) noexcept {
mMorphingBufferOffset = offset;
}
+4 -4
View File
@@ -22,19 +22,19 @@ namespace filament {
using namespace backend;
Texture* RenderTarget::getTexture(AttachmentPoint attachment) const noexcept {
Texture* RenderTarget::getTexture(AttachmentPoint const attachment) const noexcept {
return downcast(this)->getAttachment(attachment).texture;
}
uint8_t RenderTarget::getMipLevel(AttachmentPoint attachment) const noexcept {
uint8_t RenderTarget::getMipLevel(AttachmentPoint const attachment) const noexcept {
return downcast(this)->getAttachment(attachment).mipLevel;
}
RenderTarget::CubemapFace RenderTarget::getFace(AttachmentPoint attachment) const noexcept {
RenderTarget::CubemapFace RenderTarget::getFace(AttachmentPoint const attachment) const noexcept {
return downcast(this)->getAttachment(attachment).face;
}
uint32_t RenderTarget::getLayer(AttachmentPoint attachment) const noexcept {
uint32_t RenderTarget::getLayer(AttachmentPoint const attachment) const noexcept {
return downcast(this)->getAttachment(attachment).layer;
}
+49 -45
View File
@@ -27,7 +27,7 @@ namespace filament {
using namespace backend;
using namespace math;
bool RenderableManager::hasComponent(utils::Entity e) const noexcept {
bool RenderableManager::hasComponent(Entity const e) const noexcept {
return downcast(this)->hasComponent(e);
}
@@ -39,152 +39,156 @@ bool RenderableManager::empty() const noexcept {
return downcast(this)->empty();
}
utils::Entity RenderableManager::getEntity(RenderableManager::Instance i) const noexcept {
Entity RenderableManager::getEntity(Instance const i) const noexcept {
return downcast(this)->getEntity(i);
}
utils::Entity const* RenderableManager::getEntities() const noexcept {
Entity const* RenderableManager::getEntities() const noexcept {
return downcast(this)->getEntities();
}
RenderableManager::Instance
RenderableManager::getInstance(utils::Entity e) const noexcept {
RenderableManager::getInstance(Entity const e) const noexcept {
return downcast(this)->getInstance(e);
}
void RenderableManager::destroy(utils::Entity e) noexcept {
void RenderableManager::destroy(Entity const e) noexcept {
return downcast(this)->destroy(e);
}
void RenderableManager::setAxisAlignedBoundingBox(Instance instance, const Box& aabb) {
void RenderableManager::setAxisAlignedBoundingBox(Instance const instance, const Box& aabb) {
downcast(this)->setAxisAlignedBoundingBox(instance, aabb);
}
void RenderableManager::setLayerMask(Instance instance, uint8_t select, uint8_t values) noexcept {
void RenderableManager::setLayerMask(Instance const instance, uint8_t const select, uint8_t const values) noexcept {
downcast(this)->setLayerMask(instance, select, values);
}
void RenderableManager::setPriority(Instance instance, uint8_t priority) noexcept {
void RenderableManager::setPriority(Instance const instance, uint8_t const priority) noexcept {
downcast(this)->setPriority(instance, priority);
}
void RenderableManager::setChannel(Instance instance, uint8_t channel) noexcept{
void RenderableManager::setChannel(Instance const instance, uint8_t const channel) noexcept{
downcast(this)->setChannel(instance, channel);
}
void RenderableManager::setCulling(Instance instance, bool enable) noexcept {
void RenderableManager::setCulling(Instance const instance, bool const enable) noexcept {
downcast(this)->setCulling(instance, enable);
}
void RenderableManager::setCastShadows(Instance instance, bool enable) noexcept {
void RenderableManager::setCastShadows(Instance const instance, bool const enable) noexcept {
downcast(this)->setCastShadows(instance, enable);
}
void RenderableManager::setReceiveShadows(Instance instance, bool enable) noexcept {
void RenderableManager::setReceiveShadows(Instance const instance, bool const enable) noexcept {
downcast(this)->setReceiveShadows(instance, enable);
}
void RenderableManager::setScreenSpaceContactShadows(Instance instance, bool enable) noexcept {
void RenderableManager::setScreenSpaceContactShadows(Instance const instance, bool const enable) noexcept {
downcast(this)->setScreenSpaceContactShadows(instance, enable);
}
bool RenderableManager::isShadowCaster(Instance instance) const noexcept {
bool RenderableManager::isShadowCaster(Instance const instance) const noexcept {
return downcast(this)->isShadowCaster(instance);
}
bool RenderableManager::isShadowReceiver(Instance instance) const noexcept {
bool RenderableManager::isShadowReceiver(Instance const instance) const noexcept {
return downcast(this)->isShadowReceiver(instance);
}
const Box& RenderableManager::getAxisAlignedBoundingBox(Instance instance) const noexcept {
const Box& RenderableManager::getAxisAlignedBoundingBox(Instance const instance) const noexcept {
return downcast(this)->getAxisAlignedBoundingBox(instance);
}
uint8_t RenderableManager::getLayerMask(Instance instance) const noexcept {
uint8_t RenderableManager::getLayerMask(Instance const instance) const noexcept {
return downcast(this)->getLayerMask(instance);
}
size_t RenderableManager::getPrimitiveCount(Instance instance) const noexcept {
size_t RenderableManager::getPrimitiveCount(Instance const instance) const noexcept {
return downcast(this)->getPrimitiveCount(instance, 0);
}
void RenderableManager::setMaterialInstanceAt(Instance instance,
size_t primitiveIndex, MaterialInstance const* materialInstance) {
void RenderableManager::setMaterialInstanceAt(Instance const instance,
size_t const primitiveIndex, MaterialInstance const* materialInstance) {
downcast(this)->setMaterialInstanceAt(instance, 0, primitiveIndex, downcast(materialInstance));
}
void RenderableManager::clearMaterialInstanceAt(Instance instance, size_t primitiveIndex) {
downcast(this)->clearMaterialInstanceAt(instance, 0, primitiveIndex);
}
MaterialInstance* RenderableManager::getMaterialInstanceAt(
Instance instance, size_t primitiveIndex) const noexcept {
Instance const instance, size_t const primitiveIndex) const noexcept {
return downcast(this)->getMaterialInstanceAt(instance, 0, primitiveIndex);
}
void RenderableManager::setBlendOrderAt(Instance instance, size_t primitiveIndex, uint16_t order) noexcept {
void RenderableManager::setBlendOrderAt(Instance const instance, size_t const primitiveIndex, uint16_t const order) noexcept {
downcast(this)->setBlendOrderAt(instance, 0, primitiveIndex, order);
}
void RenderableManager::setGlobalBlendOrderEnabledAt(RenderableManager::Instance instance,
size_t primitiveIndex, bool enabled) noexcept {
void RenderableManager::setGlobalBlendOrderEnabledAt(Instance const instance,
size_t const primitiveIndex, bool const enabled) noexcept {
downcast(this)->setGlobalBlendOrderEnabledAt(instance, 0, primitiveIndex, enabled);
}
AttributeBitset RenderableManager::getEnabledAttributesAt(Instance instance, size_t primitiveIndex) const noexcept {
AttributeBitset RenderableManager::getEnabledAttributesAt(Instance const instance, size_t const primitiveIndex) const noexcept {
return downcast(this)->getEnabledAttributesAt(instance, 0, primitiveIndex);
}
void RenderableManager::setGeometryAt(Instance instance, size_t primitiveIndex,
PrimitiveType type, VertexBuffer* vertices, IndexBuffer* indices,
size_t offset, size_t count) noexcept {
void RenderableManager::setGeometryAt(Instance const instance, size_t const primitiveIndex,
PrimitiveType const type, VertexBuffer* vertices, IndexBuffer* indices,
size_t const offset, size_t const count) noexcept {
downcast(this)->setGeometryAt(instance, 0, primitiveIndex,
type, downcast(vertices), downcast(indices), offset, count);
}
void RenderableManager::setBones(Instance instance,
RenderableManager::Bone const* transforms, size_t boneCount, size_t offset) {
void RenderableManager::setBones(Instance const instance,
Bone const* transforms, size_t const boneCount, size_t const offset) {
downcast(this)->setBones(instance, transforms, boneCount, offset);
}
void RenderableManager::setBones(Instance instance,
mat4f const* transforms, size_t boneCount, size_t offset) {
void RenderableManager::setBones(Instance const instance,
mat4f const* transforms, size_t const boneCount, size_t const offset) {
downcast(this)->setBones(instance, transforms, boneCount, offset);
}
void RenderableManager::setSkinningBuffer(Instance instance,
SkinningBuffer* skinningBuffer, size_t count, size_t offset) {
void RenderableManager::setSkinningBuffer(Instance const instance,
SkinningBuffer* skinningBuffer, size_t const count, size_t const offset) {
downcast(this)->setSkinningBuffer(instance, downcast(skinningBuffer), count, offset);
}
void RenderableManager::setMorphWeights(Instance instance, float const* weights,
size_t count, size_t offset) {
void RenderableManager::setMorphWeights(Instance const instance, float const* weights,
size_t const count, size_t const offset) {
downcast(this)->setMorphWeights(instance, weights, count, offset);
}
void RenderableManager::setMorphTargetBufferOffsetAt(Instance instance, uint8_t level,
size_t primitiveIndex,
size_t offset) {
void RenderableManager::setMorphTargetBufferOffsetAt(Instance const instance, uint8_t const level,
size_t const primitiveIndex,
size_t const offset) {
downcast(this)->setMorphTargetBufferOffsetAt(instance, level, primitiveIndex, offset);
}
MorphTargetBuffer* RenderableManager::getMorphTargetBuffer(Instance instance) const noexcept {
MorphTargetBuffer* RenderableManager::getMorphTargetBuffer(Instance const instance) const noexcept {
return downcast(this)->getMorphTargetBuffer(instance);
}
size_t RenderableManager::getMorphTargetCount(Instance instance) const noexcept {
size_t RenderableManager::getMorphTargetCount(Instance const instance) const noexcept {
return downcast(this)->getMorphTargetCount(instance);
}
void RenderableManager::setLightChannel(Instance instance, unsigned int channel, bool enable) noexcept {
void RenderableManager::setLightChannel(Instance const instance, unsigned int const channel, bool const enable) noexcept {
downcast(this)->setLightChannel(instance, channel, enable);
}
bool RenderableManager::getLightChannel(Instance instance, unsigned int channel) const noexcept {
bool RenderableManager::getLightChannel(Instance const instance, unsigned int const channel) const noexcept {
return downcast(this)->getLightChannel(instance, channel);
}
void RenderableManager::setFogEnabled(RenderableManager::Instance instance, bool enable) noexcept {
void RenderableManager::setFogEnabled(Instance const instance, bool const enable) noexcept {
downcast(this)->setFogEnabled(instance, enable);
}
bool RenderableManager::getFogEnabled(RenderableManager::Instance instance) const noexcept {
bool RenderableManager::getFogEnabled(Instance const instance) const noexcept {
return downcast(this)->getFogEnabled(instance);
}
+8 -8
View File
@@ -42,30 +42,30 @@ void Renderer::render(View const* view) {
downcast(this)->render(downcast(view));
}
void Renderer::setPresentationTime(int64_t monotonic_clock_ns) {
void Renderer::setPresentationTime(int64_t const monotonic_clock_ns) {
downcast(this)->setPresentationTime(monotonic_clock_ns);
}
void Renderer::skipFrame(uint64_t vsyncSteadyClockTimeNano) {
void Renderer::skipFrame(uint64_t const vsyncSteadyClockTimeNano) {
downcast(this)->skipFrame(vsyncSteadyClockTimeNano);
}
bool Renderer::beginFrame(SwapChain* swapChain, uint64_t vsyncSteadyClockTimeNano) {
bool Renderer::beginFrame(SwapChain* swapChain, uint64_t const vsyncSteadyClockTimeNano) {
return downcast(this)->beginFrame(downcast(swapChain), vsyncSteadyClockTimeNano);
}
void Renderer::copyFrame(SwapChain* dstSwapChain, filament::Viewport const& dstViewport,
filament::Viewport const& srcViewport, CopyFrameFlag flags) {
filament::Viewport const& srcViewport, CopyFrameFlag const flags) {
downcast(this)->copyFrame(downcast(dstSwapChain), dstViewport, srcViewport, flags);
}
void Renderer::readPixels(uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height,
void Renderer::readPixels(uint32_t const xoffset, uint32_t const yoffset, uint32_t const width, uint32_t const height,
PixelBufferDescriptor&& buffer) {
downcast(this)->readPixels(xoffset, yoffset, width, height, std::move(buffer));
}
void Renderer::readPixels(RenderTarget* renderTarget,
uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height,
uint32_t const xoffset, uint32_t const yoffset, uint32_t const width, uint32_t const height,
PixelBufferDescriptor&& buffer) {
downcast(this)->readPixels(downcast(renderTarget),
xoffset, yoffset, width, height, std::move(buffer));
@@ -103,11 +103,11 @@ void Renderer::renderStandaloneView(View const* view) {
downcast(this)->renderStandaloneView(downcast(view));
}
void Renderer::setVsyncTime(uint64_t steadyClockTimeNano) noexcept {
void Renderer::setVsyncTime(uint64_t const steadyClockTimeNano) noexcept {
downcast(this)->setVsyncTime(steadyClockTimeNano);
}
utils::FixedCapacityVector<Renderer::FrameInfo> Renderer::getFrameInfoHistory(size_t historySize) const noexcept {
utils::FixedCapacityVector<Renderer::FrameInfo> Renderer::getFrameInfoHistory(size_t const historySize) const noexcept {
return downcast(this)->getFrameInfoHistory(historySize);
}
+7 -7
View File
@@ -55,7 +55,7 @@ RendererUtils::ColorPassOutput RendererUtils::colorPass(
FrameGraph& fg, const char* name, FEngine& engine, FView const& view,
ColorPassInput const& colorPassInput,
FrameGraphTexture::Descriptor const& colorBufferDesc,
ColorPassConfig const& config, PostProcessManager::ColorGradingConfig colorGradingConfig,
ColorPassConfig const& config, PostProcessManager::ColorGradingConfig const colorGradingConfig,
RenderPass::Executor passExecutor) noexcept {
struct ColorPassData {
@@ -273,7 +273,7 @@ std::optional<RendererUtils::ColorPassOutput> RendererUtils::refractionPass(
ColorPassInput colorPassInput,
ColorPassConfig config,
PostProcessManager::ScreenSpaceRefConfig const& ssrConfig,
PostProcessManager::ColorGradingConfig colorGradingConfig,
PostProcessManager::ColorGradingConfig const colorGradingConfig,
RenderPass const& pass) noexcept {
// find the first refractive object in channel 2
@@ -295,7 +295,7 @@ std::optional<RendererUtils::ColorPassOutput> RendererUtils::refractionPass(
config.hasScreenSpaceReflectionsOrRefractions = true;
PostProcessManager& ppm = engine.getPostProcessManager();
auto const opaquePassOutput = RendererUtils::colorPass(fg,
auto const opaquePassOutput = colorPass(fg,
"Color Pass (opaque)", engine, view, colorPassInput, {
// When rendering the opaques, we need to conserve the sample buffer,
// so create a config that specifies the sample count.
@@ -330,7 +330,7 @@ std::optional<RendererUtils::ColorPassOutput> RendererUtils::refractionPass(
// and we'd end up clearing the opaque pass. This scenario never happens because it is
// prevented in Renderer.cpp's final blit.
config.clearFlags = TargetBufferFlags::NONE;
auto transparentPassOutput = RendererUtils::colorPass(fg, "Color Pass (transparent)",
auto transparentPassOutput = colorPass(fg, "Color Pass (transparent)",
engine, view, colorPassInput, {
.width = config.physicalViewport.width,
.height = config.physicalViewport.height },
@@ -352,9 +352,9 @@ std::optional<RendererUtils::ColorPassOutput> RendererUtils::refractionPass(
}
UTILS_NOINLINE
void RendererUtils::readPixels(backend::DriverApi& driver, Handle<HwRenderTarget> renderTargetHandle,
uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height,
backend::PixelBufferDescriptor&& buffer) {
void RendererUtils::readPixels(DriverApi& driver, Handle<HwRenderTarget> renderTargetHandle,
uint32_t const xoffset, uint32_t const yoffset, uint32_t const width, uint32_t const height,
PixelBufferDescriptor&& buffer) {
FILAMENT_CHECK_PRECONDITION(buffer.type != PixelDataType::COMPRESSED)
<< "buffer.format cannot be COMPRESSED";
+1 -1
View File
@@ -99,7 +99,7 @@ public:
PostProcessManager::ColorGradingConfig colorGradingConfig,
RenderPass::Executor passExecutor) noexcept;
static std::optional<RendererUtils::ColorPassOutput> refractionPass(
static std::optional<ColorPassOutput> refractionPass(
FrameGraph& fg, FEngine& engine, FView const& view,
ColorPassInput colorPassInput,
ColorPassConfig config,
+21 -21
View File
@@ -144,30 +144,30 @@ void ResourceAllocator::terminate() noexcept {
}
RenderTargetHandle ResourceAllocator::createRenderTarget(const char* name,
TargetBufferFlags targetBufferFlags, uint32_t width, uint32_t height,
uint8_t samples, uint8_t layerCount, MRT color, TargetBufferInfo depth,
TargetBufferInfo stencil) noexcept {
TargetBufferFlags const targetBufferFlags, uint32_t const width, uint32_t const height,
uint8_t const samples, uint8_t const layerCount, MRT const color, TargetBufferInfo const depth,
TargetBufferInfo const stencil) noexcept {
auto handle = mBackend.createRenderTarget(targetBufferFlags,
width, height, samples ? samples : 1u, layerCount, color, depth, stencil);
mBackend.setDebugTag(handle.getId(), CString{ name });
return handle;
}
void ResourceAllocator::destroyRenderTarget(RenderTargetHandle h) noexcept {
void ResourceAllocator::destroyRenderTarget(RenderTargetHandle const h) noexcept {
mBackend.destroyRenderTarget(h);
}
backend::TextureHandle ResourceAllocator::createTexture(const char* name,
backend::SamplerType target, uint8_t levels, backend::TextureFormat format, uint8_t samples,
uint32_t width, uint32_t height, uint32_t depth,
std::array<backend::TextureSwizzle, 4> swizzle,
backend::TextureUsage usage) noexcept {
TextureHandle ResourceAllocator::createTexture(const char* name,
SamplerType const target, uint8_t const levels, TextureFormat const format, uint8_t samples,
uint32_t const width, uint32_t const height, uint32_t const depth,
std::array<TextureSwizzle, 4> const swizzle,
TextureUsage const usage) noexcept {
// The frame graph descriptor uses "0" to mean "auto" but the sample count that is passed to the
// backend should always be 1 or greater.
samples = samples ? samples : uint8_t(1);
using TS = backend::TextureSwizzle;
constexpr const auto defaultSwizzle = std::array<backend::TextureSwizzle, 4>{
using TS = TextureSwizzle;
constexpr const auto defaultSwizzle = std::array<TextureSwizzle, 4>{
TS::CHANNEL_0, TS::CHANNEL_1, TS::CHANNEL_2, TS::CHANNEL_3};
// do we have a suitable texture in the cache?
@@ -207,7 +207,7 @@ backend::TextureHandle ResourceAllocator::createTexture(const char* name,
return handle;
}
void ResourceAllocator::destroyTexture(TextureHandle h) noexcept {
void ResourceAllocator::destroyTexture(TextureHandle const h) noexcept {
auto const key = mDisposer->checkin(h);
if constexpr (mEnabled) {
if (UTILS_LIKELY(key.has_value())) {
@@ -225,7 +225,7 @@ ResourceAllocatorDisposerInterface& ResourceAllocator::getDisposer() noexcept {
return *mDisposer;
}
void ResourceAllocator::gc(bool skippedFrame) noexcept {
void ResourceAllocator::gc(bool const skippedFrame) noexcept {
// this is called regularly -- usually once per frame
// increase our age at each (non-skipped) frame
@@ -253,7 +253,7 @@ void ResourceAllocator::gc(bool skippedFrame) noexcept {
// maximum number of unique ages in the cache
constexpr size_t MAX_UNIQUE_AGE_COUNT = 3;
utils::bitset32 ages;
bitset32 ages;
uint32_t evictedCount = 0;
for (auto it = textureCache.begin(); it != textureCache.end();) {
size_t const ageDiff = age - it->second.age;
@@ -274,9 +274,9 @@ void ResourceAllocator::gc(bool skippedFrame) noexcept {
uint32_t bits = ages.getValue();
// remove from the set the ages we keep
for (size_t i = 0; i < MAX_UNIQUE_AGE_COUNT - 1; i++) {
bits &= ~(1 << utils::ctz(bits));
bits &= ~(1 << ctz(bits));
}
size_t const maxAge = utils::ctz(bits);
size_t const maxAge = ctz(bits);
for (auto it = textureCache.begin(); it != textureCache.end();) {
const size_t ageDiff = age - it->second.age;
if (ageDiff >= maxAge) {
@@ -289,7 +289,7 @@ void ResourceAllocator::gc(bool skippedFrame) noexcept {
}
UTILS_NOINLINE
void ResourceAllocator::dump(bool brief) const noexcept {
void ResourceAllocator::dump(bool const brief) const noexcept {
constexpr float MiB = 1.0f / float(1u << 20u);
slog.d << "# entries=" << mTextureCache.size()
<< ", sz=" << (float)mCacheSize * MiB << " MiB"
@@ -308,7 +308,7 @@ void ResourceAllocator::dump(bool brief) const noexcept {
ResourceAllocator::CacheContainer::iterator
ResourceAllocator::purge(
ResourceAllocator::CacheContainer::iterator const& pos) {
CacheContainer::iterator const& pos) {
//slog.d << "purging " << pos->second.handle.getId() << ", age=" << pos->second.age << io::endl;
mBackend.destroyTexture(pos->second.handle);
mCacheSize -= pos->second.size;
@@ -329,7 +329,7 @@ void ResourceAllocatorDisposer::terminate() noexcept {
assert_invariant(mInUseTextures.empty());
}
void ResourceAllocatorDisposer::destroy(backend::TextureHandle handle) noexcept {
void ResourceAllocatorDisposer::destroy(TextureHandle const handle) noexcept {
if (handle) {
auto r = checkin(handle);
if (r.has_value()) {
@@ -338,13 +338,13 @@ void ResourceAllocatorDisposer::destroy(backend::TextureHandle handle) noexcept
}
}
void ResourceAllocatorDisposer::checkout(backend::TextureHandle handle,
void ResourceAllocatorDisposer::checkout(TextureHandle handle,
ResourceAllocator::TextureKey key) {
mInUseTextures.emplace(handle, key);
}
std::optional<ResourceAllocator::TextureKey> ResourceAllocatorDisposer::checkin(
backend::TextureHandle handle) {
TextureHandle handle) {
// find the texture in the in-use list (it must be there!)
auto it = mInUseTextures.find(handle);
assert_invariant(it != mInUseTextures.end());
+2 -2
View File
@@ -215,8 +215,8 @@ private:
using CacheContainer = AssociativeContainer<TextureKey, TextureCachePayload>;
ResourceAllocator::CacheContainer::iterator
purge(ResourceAllocator::CacheContainer::iterator const& pos);
CacheContainer::iterator
purge(CacheContainer::iterator const& pos);
backend::DriverApi& mBackend;
std::shared_ptr<ResourceAllocatorDisposer> mDisposer;
+6 -6
View File
@@ -39,19 +39,19 @@ IndirectLight* Scene::getIndirectLight() const noexcept {
return downcast(this)->getIndirectLight();
}
void Scene::addEntity(Entity entity) {
void Scene::addEntity(Entity const entity) {
downcast(this)->addEntity(entity);
}
void Scene::addEntities(const Entity* entities, size_t count) {
void Scene::addEntities(const Entity* entities, size_t const count) {
downcast(this)->addEntities(entities, count);
}
void Scene::remove(Entity entity) {
void Scene::remove(Entity const entity) {
downcast(this)->remove(entity);
}
void Scene::removeEntities(const Entity* entities, size_t count) {
void Scene::removeEntities(const Entity* entities, size_t const count) {
downcast(this)->removeEntities(entities, count);
}
@@ -67,11 +67,11 @@ size_t Scene::getLightCount() const noexcept {
return downcast(this)->getLightCount();
}
bool Scene::hasEntity(Entity entity) const noexcept {
bool Scene::hasEntity(Entity const entity) const noexcept {
return downcast(this)->hasEntity(entity);
}
void Scene::forEach(Invocable<void(utils::Entity)>&& functor) const noexcept {
void Scene::forEach(Invocable<void(Entity)>&& functor) const noexcept {
downcast(this)->forEach(std::move(functor));
}
+49 -49
View File
@@ -84,8 +84,8 @@ void ShadowMap::terminate(FEngine& engine) {
ShadowMap::~ShadowMap() = default;
void ShadowMap::initialize(size_t lightIndex, ShadowType shadowType,
uint16_t shadowIndex, uint8_t face,
void ShadowMap::initialize(size_t const lightIndex, ShadowType const shadowType,
uint16_t const shadowIndex, uint8_t const face,
LightManager::ShadowOptions const* options) {
mLightIndex = lightIndex;
mShadowIndex = shadowIndex;
@@ -94,8 +94,8 @@ void ShadowMap::initialize(size_t lightIndex, ShadowType shadowType,
mFace = face;
}
math::mat4f ShadowMap::getDirectionalLightViewMatrix(math::float3 direction, math::float3 up,
math::float3 position) noexcept {
mat4f ShadowMap::getDirectionalLightViewMatrix(float3 direction, float3 up,
float3 position) noexcept {
// 1. we use the x-axis as the "up" reference so that the math is stable when the light
// is pointing down, which is a common case for lights.
// 2. we do the math in double to avoid some precision issues when the light is almost
@@ -104,8 +104,8 @@ math::mat4f ShadowMap::getDirectionalLightViewMatrix(math::float3 direction, mat
return FCamera::rigidTransformInverse(Mm);
}
math::mat4f ShadowMap::getPointLightViewMatrix(backend::TextureCubemapFace face,
math::float3 position) noexcept {
mat4f ShadowMap::getPointLightViewMatrix(TextureCubemapFace face,
float3 position) noexcept {
float3 direction;
switch (TextureCubemapFace(face)) {
case TextureCubemapFace::POSITIVE_X: direction = { 1, 0, 0 }; break;
@@ -121,7 +121,7 @@ math::mat4f ShadowMap::getPointLightViewMatrix(backend::TextureCubemapFace face,
ShadowMap::ShaderParameters ShadowMap::updateDirectional(FEngine& engine,
FScene::LightSoa const& lightData, size_t index,
filament::CameraInfo const& camera,
CameraInfo const& camera,
ShadowMapInfo const& shadowMapInfo,
SceneInfo const& sceneInfo,
bool useDepthClamp) noexcept {
@@ -217,10 +217,10 @@ ShadowMap::ShaderParameters ShadowMap::updateDirectional(FEngine& engine,
// Computes St the transform to use in the shader to access the shadow map texture
// i.e. it transforms a world-space vertex to a texture coordinate in the shadowmap
const auto [Mt, Mn] = ShadowMap::getTextureCoordsMapping(shadowMapInfo, getViewport());
const mat4f St = math::highPrecisionMultiply(Mt, S);
const auto [Mt, Mn] = getTextureCoordsMapping(shadowMapInfo, getViewport());
const mat4f St = highPrecisionMultiply(Mt, S);
ShadowMap::ShaderParameters shaderParameters;
ShaderParameters shaderParameters;
shaderParameters.scissorNormalized = getClampToEdgeCoords(shadowMapInfo);
// note: in texelSizeWorldSpace() below, we can use Mb * Mt * F * W because
@@ -254,7 +254,7 @@ ShadowMap::ShaderParameters ShadowMap::updateDirectional(FEngine& engine,
// The model matrix below is in fact inverted to get the view matrix and passed to the
// shader as 'viewFromWorldMatrix', and is used in the VSM case to compute the depth metric.
// (see depth_main.fs). Note that in the case of VSM, 'b' below is identity.
mCamera->setModelMatrix(FCamera::rigidTransformInverse(math::highPrecisionMultiplyd(Mv, b)));
mCamera->setModelMatrix(FCamera::rigidTransformInverse(highPrecisionMultiplyd(Mv, b)));
mCamera->setCustomProjection(mat4(Mn * F * WLMp), znear, zfar);
// for the debug camera, we need to undo the world origin
@@ -266,7 +266,7 @@ ShadowMap::ShaderParameters ShadowMap::updateDirectional(FEngine& engine,
}
ShadowMap::ShaderParameters ShadowMap::updatePunctual(
mat4f const& Mv, float outerConeAngle, float nearPlane, float farPlane,
mat4f const& Mv, float const outerConeAngle, float const nearPlane, float const farPlane,
const ShadowMapInfo& shadowMapInfo, const FLightManager::ShadowParams& params) noexcept {
const mat4f Mp = mat4f::perspective(
outerConeAngle * f::RAD_TO_DEG * 2.0f, 1.0f, nearPlane, farPlane);
@@ -274,9 +274,9 @@ ShadowMap::ShaderParameters ShadowMap::updatePunctual(
assert_invariant(shadowMapInfo.textureDimension == mOptions->mapSize);
// Final shadow transform
const mat4f S = math::highPrecisionMultiply(Mp, Mv);
const auto [Mt, Mn] = ShadowMap::getTextureCoordsMapping(shadowMapInfo, getViewport());
const mat4f St = math::highPrecisionMultiply(Mt, S);
const mat4f S = highPrecisionMultiply(Mp, Mv);
const auto [Mt, Mn] = getTextureCoordsMapping(shadowMapInfo, getViewport());
const mat4f St = highPrecisionMultiply(Mt, S);
// TODO: focus projection
// 1) focus on the casters
@@ -316,15 +316,15 @@ ShadowMap::ShaderParameters ShadowMap::updatePunctual(
// The model matrix below is in fact inverted to get the view matrix and passed to the
// shader as 'viewFromWorldMatrix', and is used in the VSM case to compute the depth metric.
// (see depth_main.fs). Note that in the case of VSM, 'b' below is identity.
mCamera->setModelMatrix(FCamera::rigidTransformInverse(math::highPrecisionMultiplyd(Mv, b)));
mCamera->setCustomProjection(math::highPrecisionMultiplyd(Mn, Mp), nearPlane, farPlane);
mCamera->setModelMatrix(FCamera::rigidTransformInverse(highPrecisionMultiplyd(Mv, b)));
mCamera->setCustomProjection(highPrecisionMultiplyd(Mn, Mp), nearPlane, farPlane);
return shaderParameters;
}
ShadowMap::ShaderParameters ShadowMap::updateSpot(FEngine& engine,
const FScene::LightSoa& lightData, size_t index,
filament::CameraInfo const&,
CameraInfo const&,
const ShadowMapInfo& shadowMapInfo,
FScene const& scene, SceneInfo sceneInfo) noexcept {
@@ -343,7 +343,7 @@ ShadowMap::ShaderParameters ShadowMap::updateSpot(FEngine& engine,
// by the light -- which should be much smaller.
if constexpr (false) {
// find decent near/far
ShadowMap::updateSceneInfoSpot(Mv, scene, sceneInfo);
updateSceneInfoSpot(Mv, scene, sceneInfo);
} else {
sceneInfo.lsCastersNearFar = { -0.01f, -radius };
}
@@ -363,7 +363,7 @@ ShadowMap::ShaderParameters ShadowMap::updateSpot(FEngine& engine,
}
ShadowMap::ShaderParameters ShadowMap::updatePoint(FEngine& engine,
const FScene::LightSoa& lightData, size_t index, filament::CameraInfo const&,
const FScene::LightSoa& lightData, size_t const index, CameraInfo const&,
const ShadowMapInfo& shadowMapInfo, FScene const& scene, uint8_t face) noexcept {
// check if this shadow map has anything to render
@@ -394,7 +394,7 @@ ShadowMap::DirectionalShadowBounds ShadowMap::computeDirectionalShadowBounds(
FEngine& engine,
float3 const direction,
FLightManager::ShadowParams params,
filament::CameraInfo const& camera,
CameraInfo const& camera,
SceneInfo const& sceneInfo,
bool useDepthClamp) noexcept {
@@ -439,7 +439,7 @@ ShadowMap::DirectionalShadowBounds ShadowMap::computeDirectionalShadowBounds(
// We compute the directional light's model matrix using the origin's as the light position.
// The choice of the light's origin initially doesn't matter for a directional light.
// This will be adjusted later because of how we compute the depth metric for VSM.
mat4f const MvAtOrigin = ShadowMap::getDirectionalLightViewMatrix(direction,
mat4f const MvAtOrigin = getDirectionalLightViewMatrix(direction,
normalize(camera.worldTransform[0].xyz));
@@ -530,7 +530,7 @@ ShadowMap::DirectionalShadowBounds ShadowMap::computeDirectionalShadowBounds(
}
mat4f ShadowMap::applyLISPSM(mat4f& Wp,
filament::CameraInfo const& camera, FLightManager::ShadowParams const& params,
CameraInfo const& camera, FLightManager::ShadowParams const& params,
mat4f const& LMp,
mat4f const& Mv,
mat4f const& LMpMv,
@@ -612,7 +612,7 @@ mat4f ShadowMap::applyLISPSM(mat4f& Wp,
return W;
}
math::mat4f ShadowMap::computeLightRotation(math::float3 const& lsDirection) noexcept {
mat4f ShadowMap::computeLightRotation(float3 const& lsDirection) noexcept {
mat4f L;
// Orient the shadow map in the direction of the view vector by constructing a
// rotation matrix in light space around the z-axis, that aligns the y-axis with the camera's
@@ -630,11 +630,11 @@ math::mat4f ShadowMap::computeLightRotation(math::float3 const& lsDirection) noe
return L;
}
math::float4 ShadowMap::computeFocusParams(
float4 ShadowMap::computeFocusParams(
mat4f const& LMpMv,
mat4f const& WLMp,
FrustumBoxIntersection const& lsShadowVolume, size_t vertexCount,
filament::CameraInfo const& camera,
CameraInfo const& camera,
float shadowFar, bool stable) noexcept {
float2 s, o;
if (stable) {
@@ -712,7 +712,7 @@ ShadowMap::TextureCoordsMapping ShadowMap::getTextureCoordsMapping(ShadowMapInfo
}
mat4f ShadowMap::computeVsmLightSpaceMatrix(const mat4f& lightSpacePcf,
const mat4f& Mv, float znear, float zfar) noexcept {
const mat4f& Mv, float const znear, float const zfar) noexcept {
// The lightSpacePcf matrix transforms coordinates from world space into (u, v, z) coordinates,
// where (u, v) are used to access the shadow map, and z is the (non-linear) PCF comparison
// value [0, 1].
@@ -732,7 +732,7 @@ mat4f ShadowMap::computeVsmLightSpaceMatrix(const mat4f& lightSpacePcf,
// This construct a frustum (similar to glFrustum or frustum), except
// it looks towards the +y axis, and assumes -1,1 for the left/right and bottom/top planes.
mat4f ShadowMap::warpFrustum(float n, float f) noexcept {
mat4f ShadowMap::warpFrustum(float const n, float const f) noexcept {
assert_invariant(f > n);
const float d = 1 / (f - n);
const float A = (f + n) * d;
@@ -746,7 +746,7 @@ mat4f ShadowMap::warpFrustum(float n, float f) noexcept {
return Wp;
}
mat4f ShadowMap::directionalLightFrustum(float near, float far) noexcept {
mat4f ShadowMap::directionalLightFrustum(float const near, float const far) noexcept {
const float d = far - near;
mat4f m;
m[2][2] = -2 / d;
@@ -755,7 +755,7 @@ mat4f ShadowMap::directionalLightFrustum(float near, float far) noexcept {
}
float2 ShadowMap::computeNearFar(const mat4f& view,
float3 const* wsVertices, size_t count) noexcept {
float3 const* wsVertices, size_t const count) noexcept {
float2 nearFar = { std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max() };
for (size_t i = 0; i < count; i++) {
// we're on the z axis in light space (looking down to -z)
@@ -767,7 +767,7 @@ float2 ShadowMap::computeNearFar(const mat4f& view,
}
float2 ShadowMap::computeNearFarOfWarpSpace(mat4f const& lightView,
float3 const* wsVertices, size_t count) noexcept {
float3 const* wsVertices, size_t const count) noexcept {
float2 nearFar = { std::numeric_limits<float>::max(), std::numeric_limits<float>::lowest() };
#pragma nounroll
for (size_t i = 0; i < count; i++) {
@@ -793,9 +793,9 @@ float4 ShadowMap::computeBoundingSphere(float3 const* vertices, size_t count) no
}
Aabb ShadowMap::compute2DBounds(const mat4f& lightView,
float3 const* wsVertices, size_t count) noexcept {
float3 const* wsVertices, size_t const count) noexcept {
Aabb bounds{};
utils::Slice<float3> const vertices{ wsVertices, count };
Slice<float3> const vertices{ wsVertices, count };
for (auto const& vertice : vertices) {
const float3 v = mat4f::project(lightView, vertice);
bounds.min.xy = min(bounds.min.xy, v.xy);
@@ -848,8 +848,8 @@ ShadowMap::Corners ShadowMap::computeFrustumCorners(
Aabb ShadowMap::computeLightFrustumBounds(mat4f const& lightView,
Aabb const& wsShadowReceiversVolume, Aabb const& wsShadowCastersVolume,
ShadowMap::SceneInfo const& sceneInfo,
bool stable, bool focusShadowCasters, bool farUsesShadowCasters) noexcept {
SceneInfo const& sceneInfo,
bool const stable, bool const focusShadowCasters, bool const farUsesShadowCasters) noexcept {
Aabb lsLightFrustumBounds{};
float const receiversFar = sceneInfo.lsReceiversNearFar[1];
@@ -880,9 +880,9 @@ Aabb ShadowMap::computeLightFrustumBounds(mat4f const& lightView,
}
void ShadowMap::snapLightFrustum(float2& s, float2& o,
double2 lsRef, int2 resolution) noexcept {
double2 const lsRef, int2 const resolution) noexcept {
auto proj2 = [](mat4 m, double2 v) -> double2 {
auto proj2 = [](mat4 m, double2 const v) -> double2 {
double2 p;
p.x = dot(double2{ m[0].x, m[1].x }, v) + m[3].x;
p.y = dot(double2{ m[0].y, m[1].y }, v) + m[3].y;
@@ -1198,7 +1198,7 @@ float ShadowMap::texelSizeWorldSpace(const mat4f& Wp, const mat4f& MbMtF,
}
template<typename Casters, typename Receivers>
void ShadowMap::visitScene(const FScene& scene, uint32_t visibleLayers,
void ShadowMap::visitScene(const FScene& scene, uint32_t const visibleLayers,
Casters casters, Receivers receivers) noexcept {
SYSTRACE_CALL();
@@ -1225,7 +1225,7 @@ void ShadowMap::visitScene(const FScene& scene, uint32_t visibleLayers,
}
ShadowMap::SceneInfo::SceneInfo(
FScene const& scene, uint8_t visibleLayers) noexcept
FScene const& scene, uint8_t const visibleLayers) noexcept
: visibleLayers(visibleLayers) {
// the code below only works with affine transforms
@@ -1237,7 +1237,7 @@ ShadowMap::SceneInfo::SceneInfo(
// Compute scene bounds in world space, as well as the light-space and view-space near/far planes
wsShadowCastersVolume = {};
wsShadowReceiversVolume = {};
ShadowMap::visitScene(scene, visibleLayers,
visitScene(scene, visibleLayers,
[&](Aabb caster, Culler::result_type) {
wsShadowCastersVolume.min = min(wsShadowCastersVolume.min, caster.min);
wsShadowCastersVolume.max = max(wsShadowCastersVolume.max, caster.max);
@@ -1263,7 +1263,7 @@ void ShadowMap::updateSceneInfoDirectional(mat4f const& Mv, FScene const& scene,
sceneInfo.lsCastersNearFar.x = max(sceneInfo.lsCastersNearFar.x, r.max.z);
sceneInfo.lsCastersNearFar.y = min(sceneInfo.lsCastersNearFar.y, r.min.z);
},
[&](Aabb receiver, Culler::result_type vis) {
[&](Aabb receiver, Culler::result_type const vis) {
// account only for objects that are visible by the camera
auto mask = 1u << VISIBLE_RENDERABLE_BIT;
if ((vis & mask) == mask) {
@@ -1284,7 +1284,7 @@ void ShadowMap::updateSceneInfoSpot(mat4f const& Mv, FScene const& scene,
sceneInfo.lsCastersNearFar = { std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max() };
// account only for objects that are visible by both the camera and the light
visitScene(scene, sceneInfo.visibleLayers,
[&](Aabb caster, Culler::result_type vis) {
[&](Aabb caster, Culler::result_type const vis) {
auto mask = VISIBLE_DYN_SHADOW_RENDERABLE;
if ((vis & mask) == mask) {
auto r = Aabb::transform(Mv.upperLeft(), Mv[3].xyz, caster);
@@ -1296,7 +1296,7 @@ void ShadowMap::updateSceneInfoSpot(mat4f const& Mv, FScene const& scene,
}
);
}
void ShadowMap::setAllocation(uint8_t layer, backend::Viewport viewport) noexcept {
void ShadowMap::setAllocation(uint8_t const layer, backend::Viewport viewport) noexcept {
mLayer = layer;
mOffset = { viewport.left, viewport.bottom };
}
@@ -1330,7 +1330,7 @@ backend::Viewport ShadowMap::getScissor() const noexcept {
}
}
math::float4 ShadowMap::getClampToEdgeCoords(ShadowMapInfo const& shadowMapInfo) const noexcept {
float4 ShadowMap::getClampToEdgeCoords(ShadowMapInfo const& shadowMapInfo) const noexcept {
float border; // shadowmap border in texels
switch (mShadowType) {
case ShadowType::DIRECTIONAL:
@@ -1365,7 +1365,7 @@ math::float4 ShadowMap::getClampToEdgeCoords(ShadowMapInfo const& shadowMapInfo)
// ------------------------------------------------------------------------------------------------
void ShadowMap::prepareCamera(Transaction const& transaction,
backend::DriverApi& driver, const CameraInfo& cameraInfo) noexcept {
DriverApi& driver, const CameraInfo& cameraInfo) noexcept {
ShadowMapDescriptorSet::prepareCamera(transaction, driver, cameraInfo);
ShadowMapDescriptorSet::prepareLodBias(transaction, 0.0f);
}
@@ -1376,12 +1376,12 @@ void ShadowMap::prepareViewport(Transaction const& transaction,
}
void ShadowMap::prepareTime(Transaction const& transaction,
FEngine const& engine, math::float4 const& userTime) noexcept {
FEngine const& engine, float4 const& userTime) noexcept {
ShadowMapDescriptorSet::prepareTime(transaction, engine, userTime);
}
void ShadowMap::prepareShadowMapping(Transaction const& transaction,
bool highPrecision) noexcept {
bool const highPrecision) noexcept {
ShadowMapDescriptorSet::prepareShadowMapping(transaction, highPrecision);
}
@@ -1390,11 +1390,11 @@ ShadowMapDescriptorSet::Transaction ShadowMap::open(DriverApi& driver) noexcept
}
void ShadowMap::commit(Transaction& transaction,
FEngine& engine, backend::DriverApi& driver) const noexcept {
FEngine& engine, DriverApi& driver) const noexcept {
mPerShadowMapUniforms.commit(transaction, engine, driver);
}
void ShadowMap::bind(backend::DriverApi& driver) const noexcept {
void ShadowMap::bind(DriverApi& driver) const noexcept {
mPerShadowMapUniforms.bind(driver);
}

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