Compare commits

..
Author SHA1 Message Date
Benjamin Doherty f3da96d424 Throw an NSException on Apple platforms when panicking 2024-03-27 16:04:49 -07:00
38 changed files with 171 additions and 321 deletions
+2
View File
@@ -7,3 +7,5 @@ for next branch cut* header.
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
## Release notes for next branch cut
- engine: Add experimental APIs `Engine::builder::paused()` and `Engine::setPaused()`
+2 -2
View File
@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.51.3'
implementation 'com.google.android.filament:filament-android:1.51.0'
}
```
@@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
iOS projects can use CocoaPods to install the latest release:
```shell
pod 'Filament', '~> 1.51.3'
pod 'Filament', '~> 1.51.0'
```
### Snapshots
-7
View File
@@ -7,13 +7,6 @@ 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.51.3
## v1.51.2
- engine: Add experimental APIs `Engine::builder::paused()` and `Engine::setPaused()`
## v1.51.1
+1 -1
View File
@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.51.3
VERSION_NAME=1.51.0
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
+1 -32
View File
@@ -1397,7 +1397,7 @@ Type
: `string`
Value
: Any of `opaque`, `transparent`, `fade`, `add`, `masked`, `multiply`, `screen`, `custom`. Defaults to `opaque`.
: Any of `opaque`, `transparent`, `fade`, `add`, `masked`, `multiply`, `screen`. Defaults to `opaque`.
Description
: Defines how/if the rendered object is blended with the content of the render target.
@@ -1420,7 +1420,6 @@ Description
of the material's output defines whether a fragment is discarded or not. Additionally,
ALPHA_TO_COVERAGE is enabled for non-translucent views. See the maskThreshold section for more
information.
- **Custom**: blending is enabled. But the blending function is user specified. See `blendFunction`.
!!! Note
When `blending` is set to `masked`, alpha to coverage is automatically enabled for the material.
@@ -1433,36 +1432,6 @@ material {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### Blending and transparency: blendFunction
Type
: `object`
Fields
: `srcRGB`, `srcA`, `dstRGB`, `dstA`
Description
: - *srcRGB*: source function applied to the RGB channels
- *srcA*: source function applied to the alpha channel
- *srcRGB*: destination function applied to the RGB channels
- *srcRGB*: destination function applied to the alpha channel
The values possible for each functions are one of `zero`, `one`, `srcColor`, `oneMinusSrcColor`,
`dstColor`, `oneMinusDstColor`, `srcAlpha`, `oneMinusSrcAlpha`, `dstAlpha`,
`oneMinusDstAlpha`, `srcAlphaSaturate`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
blending : custom,
blendFunction :
{
srcRGB: one,
srcA: one,
dstRGB: oneMinusSrcColor,
dstA: oneMinusSrcAlpha
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### Blending and transparency: postLightingBlending
Type
@@ -134,7 +134,7 @@ struct CommandType<void (Driver::*)(ARGS...)> {
public:
template<typename M, typename D>
static inline void execute(M&& method, D&& driver, CommandBase* base, intptr_t* next) {
static inline void execute(M&& method, D&& driver, CommandBase* base, intptr_t* next) noexcept {
Command* self = static_cast<Command*>(base);
*next = align(sizeof(Command));
#if DEBUG_COMMAND_STREAM
@@ -168,7 +168,7 @@ struct CommandType<void (Driver::*)(ARGS...)> {
class CustomCommand : public CommandBase {
std::function<void()> mCommand;
static void execute(Driver&, CommandBase* base, intptr_t* next);
static void execute(Driver&, CommandBase* base, intptr_t* next) noexcept;
public:
inline CustomCommand(CustomCommand&& rhs) = default;
inline explicit CustomCommand(std::function<void()> cmd)
@@ -76,7 +76,7 @@ public:
// the fn function will execute a batch of driver commands
// this gives the driver a chance to wrap their execution in a meaningful manner
// the default implementation simply calls fn
virtual void execute(std::function<void(void)> const& fn);
virtual void execute(std::function<void(void)> const& fn) noexcept;
// This is called on debug build, or when enabled manually on the backend thread side.
virtual void debugCommandBegin(CommandStream* cmds,
@@ -65,7 +65,7 @@ public:
*
*/
template<typename D, typename ... ARGS>
Handle<D> allocateAndConstruct(ARGS&& ... args) {
Handle<D> allocateAndConstruct(ARGS&& ... args) noexcept {
Handle<D> h{ allocateHandle<D>() };
D* addr = handle_cast<D*>(h);
new(addr) D(std::forward<ARGS>(args)...);
@@ -97,7 +97,7 @@ public:
*/
template<typename D, typename B, typename ... ARGS>
typename std::enable_if_t<std::is_base_of_v<B, D>, D>*
destroyAndConstruct(Handle<B> const& handle, ARGS&& ... args) {
destroyAndConstruct(Handle<B> const& handle, ARGS&& ... args) noexcept {
assert_invariant(handle);
D* addr = handle_cast<D*>(const_cast<Handle<B>&>(handle));
assert_invariant(addr);
@@ -163,7 +163,7 @@ public:
inline typename std::enable_if_t<
std::is_pointer_v<Dp> &&
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
handle_cast(Handle<B>& handle) {
handle_cast(Handle<B>& handle) noexcept {
assert_invariant(handle);
auto [p, tag] = handleToPointer(handle.getId());
@@ -185,7 +185,7 @@ public:
inline typename std::enable_if_t<
std::is_pointer_v<Dp> &&
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
handle_cast(Handle<B> const& handle) {
handle_cast(Handle<B> const& handle) noexcept {
return handle_cast<Dp>(const_cast<Handle<B>&>(handle));
}
@@ -317,7 +317,7 @@ private:
return (id & HANDLE_HEAP_FLAG) == 0u;
}
HandleBase::HandleId allocateHandleSlow(size_t size);
HandleBase::HandleId allocateHandleSlow(size_t size) noexcept;
void deallocateHandleSlow(HandleBase::HandleId id, size_t size) noexcept;
// We inline this because it's just 4 instructions in the fast case
+1 -1
View File
@@ -149,7 +149,7 @@ void CommandType<void (Driver::*)(ARGS...)>::Command<METHOD>::log() noexcept {
// ------------------------------------------------------------------------------------------------
void CustomCommand::execute(Driver&, CommandBase* base, intptr_t* next) {
void CustomCommand::execute(Driver&, CommandBase* base, intptr_t* next) noexcept {
*next = CustomCommand::align(sizeof(CustomCommand));
static_cast<CustomCommand*>(base)->mCommand();
static_cast<CustomCommand*>(base)->~CustomCommand();
+1 -1
View File
@@ -214,7 +214,7 @@ size_t Driver::getElementTypeSize(ElementType type) noexcept {
Driver::~Driver() noexcept = default;
void Driver::execute(std::function<void(void)> const& fn) {
void Driver::execute(std::function<void(void)> const& fn) noexcept {
fn();
}
+1 -1
View File
@@ -107,7 +107,7 @@ void* HandleAllocator<P0, P1, P2>::handleToPointerSlow(HandleBase::HandleId id)
}
template <size_t P0, size_t P1, size_t P2>
HandleBase::HandleId HandleAllocator<P0, P1, P2>::allocateHandleSlow(size_t size) {
HandleBase::HandleId HandleAllocator<P0, P1, P2>::allocateHandleSlow(size_t size) noexcept {
void* p = ::malloc(size);
std::unique_lock lock(mLock);
+1 -1
View File
@@ -1634,7 +1634,7 @@ void MetalDriver::bindPipeline(PipelineState ps) {
return;
}
functions.validate();
ASSERT_PRECONDITION(bool(functions), "Attempting to bind an invalid Metal program.");
auto [fragment, vertex] = functions.getRasterFunctions();
+8 -10
View File
@@ -724,19 +724,10 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
GLenum internalFormat = getInternalFormat(format);
assert_invariant(internalFormat);
if (any(usage & TextureUsage::PROTECTED)) {
if (UTILS_UNLIKELY(usage & TextureUsage::PROTECTED)) {
// renderbuffers don't have a protected mode, so we need to use a texture
// because protected textures are only supported on GLES 3.2, MSAA will be available.
usage |= TextureUsage::SAMPLEABLE;
} else if (any(usage & TextureUsage::UPLOADABLE)) {
// if we have the uploadable flag, we also need to use a texture
usage |= TextureUsage::SAMPLEABLE;
} else if (target != SamplerType::SAMPLER_2D) {
// renderbuffers can only be 2D
usage |= TextureUsage::SAMPLEABLE;
} else if (levels > 1) {
// renderbuffers can't have mip levels
usage |= TextureUsage::SAMPLEABLE;
}
auto& gl = mContext;
@@ -812,6 +803,13 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
textureStorage(t, w, h, depth, bool(usage & TextureUsage::PROTECTED));
}
} else {
assert_invariant(any(usage & (
TextureUsage::COLOR_ATTACHMENT |
TextureUsage::DEPTH_ATTACHMENT |
TextureUsage::STENCIL_ATTACHMENT)));
assert_invariant(levels == 1);
assert_invariant(target == SamplerType::SAMPLER_2D);
assert_invariant(none(usage & TextureUsage::PROTECTED));
t->gl.internalFormat = internalFormat;
t->gl.target = GL_RENDERBUFFER;
glGenRenderbuffers(1, &t->gl.id);
+4 -4
View File
@@ -268,13 +268,13 @@ private:
HandleAllocatorGL mHandleAllocator;
template<typename D, typename ... ARGS>
Handle<D> initHandle(ARGS&& ... args) {
Handle<D> initHandle(ARGS&& ... args) noexcept {
return mHandleAllocator.allocateAndConstruct<D>(std::forward<ARGS>(args) ...);
}
template<typename D, typename B, typename ... ARGS>
typename std::enable_if<std::is_base_of<B, D>::value, D>::type*
construct(Handle<B> const& handle, ARGS&& ... args) {
construct(Handle<B> const& handle, ARGS&& ... args) noexcept {
return mHandleAllocator.destroyAndConstruct<D, B>(handle, std::forward<ARGS>(args) ...);
}
@@ -288,7 +288,7 @@ private:
typename std::enable_if_t<
std::is_pointer_v<Dp> &&
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
handle_cast(Handle<B>& handle) {
handle_cast(Handle<B>& handle) noexcept {
return mHandleAllocator.handle_cast<Dp, B>(handle);
}
@@ -296,7 +296,7 @@ private:
inline typename std::enable_if_t<
std::is_pointer_v<Dp> &&
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
handle_cast(Handle<B> const& handle) {
handle_cast(Handle<B> const& handle) noexcept {
return mHandleAllocator.handle_cast<Dp, B>(handle);
}
-10
View File
@@ -277,16 +277,6 @@ bool MaterialParser::getBlendingMode(BlendingMode* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::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);
(*value)[0] = BlendFunction((blendFunctions >> 24) & 0xFF);
(*value)[1] = BlendFunction((blendFunctions >> 16) & 0xFF);
(*value)[2] = BlendFunction((blendFunctions >> 8) & 0xFF);
(*value)[3] = BlendFunction((blendFunctions >> 0) & 0xFF);
return result;
}
bool MaterialParser::getMaskThreshold(float* value) const noexcept {
return mImpl.getFromSimpleChunk(ChunkType::MaterialMaskThreshold, value);
}
-1
View File
@@ -102,7 +102,6 @@ public:
bool getShading(Shading*) const noexcept;
bool getBlendingMode(BlendingMode*) const noexcept;
bool getCustomBlendFunction(std::array<backend::BlendFunction, 4>*) const noexcept;
bool getMaskThreshold(float*) const noexcept;
bool getAlphaToCoverageSet(bool*) const noexcept;
bool getAlphaToCoverage(bool*) const noexcept;
+4 -1
View File
@@ -450,8 +450,11 @@ PostProcessManager::StructurePassOutput PostProcessManager::structure(FrameGraph
.levels = uint8_t(levelCount),
.format = isES2 ? TextureFormat::DEPTH24 : TextureFormat::DEPTH32F });
// workaround: since we have levels, this implies SAMPLEABLE (because of the gl
// backend, which implements non-sampleables with renderbuffers, which don't have levels).
// (should the gl driver revert to textures, in that case?)
data.depth = builder.write(data.depth,
FrameGraphTexture::Usage::DEPTH_ATTACHMENT);
FrameGraphTexture::Usage::DEPTH_ATTACHMENT | FrameGraphTexture::Usage::SAMPLEABLE);
if (config.picking) {
data.picking = builder.createTexture("Picking Buffer", {
+8 -19
View File
@@ -16,35 +16,17 @@
#include "RendererUtils.h"
#include "PostProcessManager.h"
#include "details/Engine.h"
#include "details/View.h"
#include "fg/FrameGraph.h"
#include "fg/FrameGraphId.h"
#include "fg/FrameGraphResources.h"
#include "fg/FrameGraphTexture.h"
#include <filament/Options.h>
#include <filament/RenderableManager.h>
#include <filament/Viewport.h>
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <backend/PixelBufferDescriptor.h>
#include <utils/BitmaskEnum.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/Panic.h>
#include <algorithm>
#include <utility>
#include <stddef.h>
#include <stdint.h>
namespace filament {
using namespace backend;
@@ -171,9 +153,16 @@ FrameGraphId<FrameGraphTexture> RendererUtils::colorPass(
data.depth = builder.read(data.depth, FrameGraphTexture::Usage::DEPTH_ATTACHMENT);
data.color = builder.write(data.color, FrameGraphTexture::Usage::COLOR_ATTACHMENT);
data.depth = builder.write(data.depth, FrameGraphTexture::Usage::DEPTH_ATTACHMENT);
if (engine.getConfig().stereoscopicType == StereoscopicType::MULTIVIEW) {
// Add sampleable usage flag for depth in multiview rendering, othewise it's
// treated as renderbuffer in the backend and crashed.
data.depth = builder.write(data.depth,
FrameGraphTexture::Usage::DEPTH_ATTACHMENT |
FrameGraphTexture::Usage::SAMPLEABLE);
layerCount = engine.getConfig().stereoscopicEyeCount;
} else {
data.depth = builder.write(data.depth,
FrameGraphTexture::Usage::DEPTH_ATTACHMENT);
}
/*
+6 -8
View File
@@ -323,8 +323,12 @@ FMaterial::FMaterial(FEngine& engine, const Material::Builder& builder)
parser->getMaskThreshold(&mMaskThreshold);
}
if (mBlendingMode == BlendingMode::CUSTOM) {
parser->getCustomBlendFunction(&mCustomBlendFunctions);
// The fade blending mode only affects shading. For proper sorting we need to
// treat this blending mode as a regular transparent blending operation.
if (UTILS_UNLIKELY(mBlendingMode == BlendingMode::FADE)) {
mRenderBlendingMode = BlendingMode::TRANSPARENT;
} else {
mRenderBlendingMode = mBlendingMode;
}
if (mShading == Shading::UNLIT) {
@@ -377,12 +381,6 @@ FMaterial::FMaterial(FEngine& engine, const Material::Builder& builder)
mRasterState.blendFunctionDstAlpha = BlendFunction::ONE_MINUS_SRC_COLOR;
mRasterState.depthWrite = false;
break;
case BlendingMode::CUSTOM:
mRasterState.blendFunctionSrcRGB = mCustomBlendFunctions[0];
mRasterState.blendFunctionSrcAlpha = mCustomBlendFunctions[1];
mRasterState.blendFunctionDstRGB = mCustomBlendFunctions[2];
mRasterState.blendFunctionDstAlpha = mCustomBlendFunctions[3];
mRasterState.depthWrite = false;
}
bool depthWriteSet = false;
+2 -1
View File
@@ -127,6 +127,7 @@ public:
Shading getShading() const noexcept { return mShading; }
Interpolation getInterpolation() const noexcept { return mInterpolation; }
BlendingMode getBlendingMode() const noexcept { return mBlendingMode; }
BlendingMode getRenderBlendingMode() const noexcept { return mRenderBlendingMode; }
VertexDomain getVertexDomain() const noexcept { return mVertexDomain; }
MaterialDomain getMaterialDomain() const noexcept { return mMaterialDomain; }
CullingMode getCullingMode() const noexcept { return mCullingMode; }
@@ -222,13 +223,13 @@ private:
mutable std::array<backend::Handle<backend::HwProgram>, VARIANT_COUNT> mCachedPrograms;
backend::RasterState mRasterState;
BlendingMode mRenderBlendingMode = BlendingMode::OPAQUE;
TransparencyMode mTransparencyMode = TransparencyMode::DEFAULT;
bool mIsVariantLit = false;
backend::FeatureLevel mFeatureLevel = backend::FeatureLevel::FEATURE_LEVEL_1;
Shading mShading = Shading::UNLIT;
BlendingMode mBlendingMode = BlendingMode::OPAQUE;
std::array<backend::BlendFunction, 4> mCustomBlendFunctions = {};
Interpolation mInterpolation = Interpolation::SMOOTH;
VertexDomain mVertexDomain = VertexDomain::OBJECT;
MaterialDomain mMaterialDomain = MaterialDomain::SURFACE;
+2 -2
View File
@@ -1,12 +1,12 @@
Pod::Spec.new do |spec|
spec.name = "Filament"
spec.version = "1.51.3"
spec.version = "1.51.0"
spec.license = { :type => "Apache 2.0", :file => "LICENSE" }
spec.homepage = "https://google.github.io/filament"
spec.authors = "Google LLC."
spec.summary = "Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WASM/WebGL."
spec.platform = :ios, "11.0"
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.51.3/filament-v1.51.3-ios.tgz" }
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.51.0/filament-v1.51.0-ios.tgz" }
# Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon.
spec.pod_target_xcconfig = {
@@ -59,7 +59,6 @@ enum UTILS_PUBLIC ChunkType : uint64_t {
MaterialFeatureLevel = charTo64bitNum("MAT_FEAT"),
MaterialShading = charTo64bitNum("MAT_SHAD"),
MaterialBlendingMode = charTo64bitNum("MAT_BLEN"),
MaterialBlendFunction = charTo64bitNum("MAT_BLFN"),
MaterialTransparencyMode = charTo64bitNum("MAT_TRMD"),
MaterialMaskThreshold = charTo64bitNum("MAT_THRS"),
MaterialShadowMultiplier = charTo64bitNum("MAT_SHML"),
@@ -80,8 +80,6 @@ enum class BlendingMode : uint8_t {
MULTIPLY,
//! material brightens what's behind it
SCREEN,
//! custom blending function
CUSTOM,
};
/**
@@ -227,7 +227,6 @@ public:
using ShaderQuality = filament::ShaderQuality;
using BlendingMode = filament::BlendingMode;
using BlendFunction = filament::backend::BlendFunction;
using Shading = filament::Shading;
using Interpolation = filament::Interpolation;
using VertexDomain = filament::VertexDomain;
@@ -408,15 +407,6 @@ public:
*/
MaterialBuilder& blending(BlendingMode blending) noexcept;
/**
* Set the blend function for this material. blending must be et to CUSTOM.
*/
MaterialBuilder& customBlendFunctions(
BlendFunction srcRGB,
BlendFunction srcA,
BlendFunction dstRGB,
BlendFunction dstA) noexcept;
/**
* Set the blending mode of the post-lighting color for this material.
* Only OPAQUE, TRANSPARENT and ADD are supported, the default is TRANSPARENT.
@@ -838,7 +828,6 @@ private:
FeatureLevel mFeatureLevel = FeatureLevel::FEATURE_LEVEL_1;
BlendingMode mBlendingMode = BlendingMode::OPAQUE;
BlendingMode mPostLightingBlendingMode = BlendingMode::TRANSPARENT;
std::array<BlendFunction, 4> mCustomBlendFunctions = {};
CullingMode mCullingMode = CullingMode::BACK;
Shading mShading = Shading::LIT;
MaterialDomain mMaterialDomain = MaterialDomain::SURFACE;
-20
View File
@@ -388,16 +388,6 @@ MaterialBuilder& MaterialBuilder::blending(BlendingMode blending) noexcept {
return *this;
}
MaterialBuilder& MaterialBuilder::customBlendFunctions(
BlendFunction srcRGB, BlendFunction srcA,
BlendFunction dstRGB, BlendFunction dstA) noexcept {
mCustomBlendFunctions[0] = srcRGB;
mCustomBlendFunctions[1] = srcA;
mCustomBlendFunctions[2] = dstRGB;
mCustomBlendFunctions[3] = dstA;
return *this;
}
MaterialBuilder& MaterialBuilder::postLightingBlending(BlendingMode blending) noexcept {
mPostLightingBlendingMode = blending;
return *this;
@@ -1520,16 +1510,6 @@ void MaterialBuilder::writeCommonChunks(ChunkContainer& container, MaterialInfo&
container.emplace<bool>(ChunkType::MaterialDoubleSided, mDoubleSided);
container.emplace<uint8_t>(ChunkType::MaterialBlendingMode,
static_cast<uint8_t>(mBlendingMode));
if (mBlendingMode == BlendingMode::CUSTOM) {
uint32_t const blendFunctions =
(uint32_t(mCustomBlendFunctions[0]) << 24) |
(uint32_t(mCustomBlendFunctions[1]) << 16) |
(uint32_t(mCustomBlendFunctions[2]) << 8) |
(uint32_t(mCustomBlendFunctions[3]) << 0);
container.emplace< uint32_t >(ChunkType::MaterialBlendFunction, blendFunctions);
}
container.emplace<uint8_t>(ChunkType::MaterialTransparencyMode,
static_cast<uint8_t>(mTransparencyMode));
container.emplace<uint8_t>(ChunkType::MaterialReflectionMode,
@@ -157,9 +157,6 @@ void ShaderGenerator::generateSurfaceMaterialVariantDefines(utils::io::sstream&
case BlendingMode::SCREEN:
CodeGenerator::generateDefine(out, "BLEND_MODE_SCREEN", true);
break;
case BlendingMode::CUSTOM:
CodeGenerator::generateDefine(out, "BLEND_MODE_CUSTOM", true);
break;
}
switch (material.postLightingBlendingMode) {
@@ -178,9 +175,6 @@ void ShaderGenerator::generateSurfaceMaterialVariantDefines(utils::io::sstream&
case BlendingMode::SCREEN:
CodeGenerator::generateDefine(out, "POST_LIGHTING_BLEND_MODE_SCREEN", true);
break;
case BlendingMode::CUSTOM:
CodeGenerator::generateDefine(out, "POST_LIGHTING_BLEND_MODE_CUSTOM", true);
break;
default:
break;
}
-1
View File
@@ -338,7 +338,6 @@ const char* toString(BlendingMode blendingMode) noexcept {
case BlendingMode::FADE: return "fade";
case BlendingMode::MULTIPLY: return "multiply";
case BlendingMode::SCREEN: return "screen";
case BlendingMode::CUSTOM: return "custom";
}
}
-1
View File
@@ -65,7 +65,6 @@ const char* toString(BlendingMode blendingMode) noexcept {
case BlendingMode::FADE: return "fade";
case BlendingMode::MULTIPLY: return "multiply";
case BlendingMode::SCREEN: return "screen";
case BlendingMode::CUSTOM: return "custom";
}
return "--";
}
-2
View File
@@ -76,8 +76,6 @@ static string_view readBlendingMode(string_view cursor, BlendingMode* blending)
*blending = BlendingMode::MULTIPLY;
} else if (sz = readPrefix("screen"sv, cursor); sz > 0) {
*blending = BlendingMode::SCREEN;
} else if (sz = readPrefix("custom"sv, cursor); sz > 0) {
*blending = BlendingMode::CUSTOM;
}
return { cursor.data(), sz };
}
+5
View File
@@ -87,6 +87,7 @@ if (LINUX OR ANDROID)
list(APPEND SRCS src/linux/Path.cpp)
endif()
if (APPLE)
list(APPEND SRCS src/darwin/Exception.mm)
list(APPEND SRCS src/darwin/Path.mm)
list(APPEND SRCS src/darwin/Systrace.cpp)
endif()
@@ -122,6 +123,10 @@ if (LINUX)
target_link_libraries(${TARGET} PRIVATE dl)
endif()
if (APPLE AND NOT IOS)
target_link_libraries(${TARGET} PRIVATE "-framework Cocoa")
endif()
# ==================================================================================================
# Installation
# ==================================================================================================
+21 -36
View File
@@ -250,71 +250,54 @@ namespace utils {
*/
class UTILS_PUBLIC Panic {
public:
using PanicHandlerCallback = void(*)(void* user, Panic const& panic);
/**
* Sets a user-defined handler for the Panic. If exceptions are enabled, the concrete Panic
* object will be thrown upon return; moreover it is acceptable to throw from the provided
* callback, but it is unsafe to throw the Panic object itself, since it's just an interface.
* It is also acceptable to abort from the callback. If exceptions are not enabled, std::abort()
* will be automatically called upon return.
*
* The PanicHandlerCallback can be called from any thread.
*
* Caveat: this API can misbehave if is used as a static library in multiple translation units,
* some of these translation units might not see the callback.
*
* @param handler pointer to the user defined handler for the Panic
* @param user user pointer given back to the callback
*/
static void setPanicHandler(PanicHandlerCallback handler, void* user) noexcept;
virtual ~Panic() noexcept;
/**
* @return a formatted and detailed description of the error including all available
* information.
* @return a detailed description of the error
* @see std::exception
*/
virtual const char* what() const noexcept = 0;
/**
* Get the reason string for the panic
* @return a C string containing the reason for the panic
* Get the reason for the panic.
* @return a C string containing the reason for the panic.
*/
virtual const char* getReason() const noexcept = 0;
/**
* Get the function name where the panic was detected. On debug build the fully qualified
* function name is returned; on release builds only the function name is.
* Get the type of the panic. When compiled without RTTI, this returns a generic type name.
* @return a C string containing the type of the panic.
*/
virtual const char* getType() const noexcept = 0;
/**
* Get the function name where the panic was detected
* @return a C string containing the function name where the panic was detected
*/
virtual const char* getFunction() const noexcept = 0;
/**
* Get the file name where the panic was detected. Only available on debug builds.
* Get the file name where the panic was detected
* @return a C string containing the file name where the panic was detected
*/
virtual const char* getFile() const noexcept = 0;
/**
* Get the line number in the file where the panic was detected. Only available on debug builds.
* Get the line number in the file where the panic was detected
* @return an integer containing the line number in the file where the panic was detected
*/
virtual int getLine() const noexcept = 0;
/**
* Get the CallStack when the panic was detected if available.
* @return the CallStack when the panic was detected
*/
virtual const CallStack& getCallStack() const noexcept = 0;
/**
* Logs this exception to the system-log
*/
virtual void log() const noexcept = 0;
/**
* Get the CallStack when the panic was detected
* @return the CallStack when the panic was detected
*/
virtual const CallStack& getCallStack() const noexcept = 0;
};
// -----------------------------------------------------------------------------------------------
@@ -335,6 +318,7 @@ public:
// Panic interface
const char* getReason() const noexcept override;
const char* getType() const noexcept override;
const char* getFunction() const noexcept override;
const char* getFile() const noexcept override;
int getLine() const noexcept override;
@@ -399,7 +383,8 @@ private:
char const* const m_function = nullptr;
char const* const m_file = nullptr;
const int m_line = -1;
mutable std::string m_msg;
std::string m_msg;
std::string m_type;
};
namespace details {
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_UTILS_DARWIN_EXCEPTION_H
#define TNT_UTILS_DARWIN_EXCEPTION_H
#include <utils/Panic.h>
#include <utils/compiler.h>
namespace utils::details {
void throwDarwinException(const Panic& exception) UTILS_NORETURN;
}
#endif // TNT_UTILS_DARWIN_EXCEPTION_H
-1
View File
@@ -20,7 +20,6 @@
#include <utils/compiler.h>
namespace utils {
UTILS_PUBLIC
void panic(const char *func, const char * file, int line, const char *assertion) noexcept;
} // namespace filament
+26 -79
View File
@@ -14,64 +14,21 @@
* limitations under the License.
*/
#include <utils/compiler.h>
#include <utils/Panic.h>
#include <utils/Log.h>
#include <utils/ostream.h>
#if defined(__APPLE__)
#include <utils/darwin/Exception.h>
#endif
#include <atomic>
#include <cstdarg>
#include <cstdlib>
#include <cstring>
#include <mutex>
#include <new>
#include <string>
#include <utility>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <utils/Log.h>
namespace utils {
// ------------------------------------------------------------------------------------------------
class UserPanicHandler {
struct CallBack {
Panic::PanicHandlerCallback handler = nullptr;
void* user = nullptr;
void call(Panic const& panic) const noexcept {
if (UTILS_UNLIKELY(handler)) {
handler(user, panic);
}
}
};
mutable std::mutex mLock{};
CallBack mCallBack{};
CallBack getCallback() const noexcept {
std::lock_guard const lock(mLock);
return mCallBack;
}
public:
static UserPanicHandler& get() noexcept {
static UserPanicHandler data;
return data;
}
void call(Panic const& panic) const noexcept {
getCallback().call(panic);
}
void set(Panic::PanicHandlerCallback handler, void* user) noexcept {
std::lock_guard const lock(mLock);
mCallBack = { handler, user };
}
};
// ------------------------------------------------------------------------------------------------
static std::string formatString(const char* format, va_list args) noexcept {
std::string reason;
@@ -82,12 +39,10 @@ static std::string formatString(const char* format, va_list args) noexcept {
if (n >= 0) {
++n; // for the nul-terminating char
char* const buf = new(std::nothrow) char[n];
if (buf) {
vsnprintf(buf, size_t(n), format, args);
reason.assign(buf);
delete [] buf;
}
char* buf = new char[n];
vsnprintf(buf, size_t(n), format, args);
reason.assign(buf);
delete [] buf;
}
return reason;
}
@@ -112,16 +67,8 @@ static std::string panicString(
#endif
}
// ------------------------------------------------------------------------------------------------
Panic::~Panic() noexcept = default;
void Panic::setPanicHandler(PanicHandlerCallback handler, void* user) noexcept {
UserPanicHandler::get().set(handler, user);
}
// ------------------------------------------------------------------------------------------------
template<typename T>
TPanic<T>::TPanic(std::string reason) :
m_reason(std::move(reason)) {
@@ -150,6 +97,11 @@ const char* TPanic<T>::getReason() const noexcept {
return m_reason.c_str();
}
template<typename T>
const char* TPanic<T>::getType() const noexcept {
return m_type.c_str();
}
template<typename T>
const char* TPanic<T>::getFunction() const noexcept {
return m_function;
@@ -178,13 +130,12 @@ void TPanic<T>::log() const noexcept {
template<typename T>
void TPanic<T>::buildMessage() {
std::string type;
#if UTILS_HAS_RTTI
type = CallStack::demangleTypeName(typeid(T).name()).c_str();
m_type = CallStack::demangleTypeName(typeid(T).name()).c_str();
#else
type = "Panic";
m_type = "Panic";
#endif
m_msg = panicString(type, m_function, m_line, m_file, m_reason.c_str());
m_msg = panicString(m_type, m_function, m_line, m_file, m_reason.c_str());
}
UTILS_ALWAYS_INLINE
@@ -197,22 +148,18 @@ template<typename T>
void TPanic<T>::panic(char const* function, char const* file, int line, const char* format, ...) {
va_list args;
va_start(args, format);
std::string const reason(formatString(format, args));
std::string reason(formatString(format, args));
va_end(args);
T e(function, formatFile(file), line, reason);
// always log the Panic at the point it is detected
e.log();
// Call the user provided handler
UserPanicHandler::get().call(e);
// if exceptions are enabled, throw now.
#ifdef __EXCEPTIONS
throw e;
#if defined(__APPLE__)
details::throwDarwinException(e);
#endif
// and finally abort if we somehow get here
#ifdef __EXCEPTIONS
throw e;
#endif
std::abort();
}
@@ -223,7 +170,7 @@ namespace details {
void panicLog(char const* function, char const* file, int line, const char* format, ...) noexcept {
va_list args;
va_start(args, format);
std::string const reason(formatString(format, args));
std::string reason(formatString(format, args));
va_end(args);
const std::string msg = panicString("" /* no extra message */,
+35
View File
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <utils/Panic.h>
#include <Foundation/Foundation.h>
namespace utils::details {
void throwDarwinException(const Panic& exception) {
// Turn this exception into an NSException and raise it.
// This is allowed even if we're built without Objective-C exceptions (-fno-objc-exceptions).
[[NSException exceptionWithName:@(exception.getType())
reason:@(exception.getReason())
userInfo:@{
@"file" : @(exception.getFile()),
@"line" : @(exception.getLine()),
@"function" : @(exception.getFunction())
}] raise];
}
}
@@ -671,7 +671,6 @@ static bool processBlending(MaterialBuilder& builder, const JsonishValue& value)
{ "fade", MaterialBuilder::BlendingMode::FADE },
{ "multiply", MaterialBuilder::BlendingMode::MULTIPLY },
{ "screen", MaterialBuilder::BlendingMode::SCREEN },
{ "custom", MaterialBuilder::BlendingMode::CUSTOM },
};
auto jsonString = value.toJsonString();
if (!isStringValidEnum(strToEnum, jsonString->getString())) {
@@ -682,52 +681,6 @@ static bool processBlending(MaterialBuilder& builder, const JsonishValue& value)
return true;
}
static bool processBlendFunction(MaterialBuilder& builder, const JsonishValue& value) {
static const std::unordered_map<std::string, MaterialBuilder::BlendFunction> strToEnum{
{ "zero", MaterialBuilder::BlendFunction::ZERO },
{ "one", MaterialBuilder::BlendFunction::ONE },
{ "srcColor", MaterialBuilder::BlendFunction::SRC_COLOR },
{ "oneMinusSrcColor", MaterialBuilder::BlendFunction::ONE_MINUS_SRC_COLOR },
{ "dstColor", MaterialBuilder::BlendFunction::DST_COLOR },
{ "oneMinusDstColor", MaterialBuilder::BlendFunction::ONE_MINUS_DST_COLOR },
{ "srcAlpha", MaterialBuilder::BlendFunction::SRC_ALPHA },
{ "oneMinusSrcAlpha", MaterialBuilder::BlendFunction::ONE_MINUS_SRC_ALPHA },
{ "dstAlpha", MaterialBuilder::BlendFunction::DST_ALPHA },
{ "oneMinusDstAlpha", MaterialBuilder::BlendFunction::ONE_MINUS_DST_ALPHA },
{ "srcAlphaSaturate", MaterialBuilder::BlendFunction::SRC_ALPHA_SATURATE },
};
if (value.getType() != JsonishValue::Type::OBJECT) {
std::cerr << "blendFunction must be an OBJECT." << std::endl;
}
JsonishObject const* const jsonObject = value.toJsonObject();
MaterialBuilder::BlendFunction srcRGB, srcA, dstRGB, dstA;
std::pair<const char*, MaterialBuilder::BlendFunction*> functions[] = {
{ "srcRGB", &srcRGB },
{ "srcA", &srcA },
{ "dstRGB", &dstRGB },
{ "dstA", &dstA },
};
for (auto&& entry : functions) {
const char* key = entry.first;
const JsonishValue* v = jsonObject->getValue(key);
if (!v) {
std::cerr << "blendFunction: entry without '" << key << "' key." << std::endl;
return false;
}
if (v->getType() != JsonishValue::STRING) {
std::cerr << "blendFunction: '" << key << "' value must be STRING." << std::endl;
return false;
}
*entry.second = stringToEnum(strToEnum, v->toJsonString()->getString());
}
builder.customBlendFunctions(srcRGB, srcA, dstRGB, dstA);
return true;
}
static bool processPostLightingBlending(MaterialBuilder& builder, const JsonishValue& value) {
static const std::unordered_map<std::string, MaterialBuilder::BlendingMode> strToEnum {
{ "add", MaterialBuilder::BlendingMode::ADD },
@@ -1241,7 +1194,6 @@ ParametersProcessor::ParametersProcessor() {
mParameters["variables"] = { &processVariables, Type::ARRAY };
mParameters["requires"] = { &processRequires, Type::ARRAY };
mParameters["blending"] = { &processBlending, Type::STRING };
mParameters["blendFunction"] = { &processBlendFunction, Type::OBJECT };
mParameters["postLightingBlending"] = { &processPostLightingBlending, Type::STRING };
mParameters["vertexDomain"] = { &processVertexDomain, Type::STRING };
mParameters["culling"] = { &processCulling, Type::STRING };
+2 -2
View File
@@ -369,8 +369,8 @@ using EntityVector = std::vector<utils::Entity>;
register_vector<std::string>("RegistryKeys");
register_vector<utils::Entity>("EntityVector");
register_vector<allow_raw_pointer<FilamentInstance*>>("AssetInstanceVector");
register_vector<allow_raw_pointer<MaterialInstance*>>("MaterialInstanceVector");
register_vector<FilamentInstance*>("AssetInstanceVector");
register_vector<MaterialInstance*>("MaterialInstanceVector");
// CORE FILAMENT CLASSES
// ---------------------
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "filament",
"version": "1.51.3",
"version": "1.51.0",
"description": "Real-time physically based rendering engine",
"main": "filament.js",
"module": "filament.js",