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
Nimrod Gileadi a068143953 Add semicolons to code snippet in AssetLoader.h (#7717) 2024-03-27 17:24:10 +00:00
Powei Feng 90d90094dc Bump material version to 51 in MaterialEnums.h 2024-03-26 14:37:13 -07:00
Sungun Park 54df4524eb Improve multiview shader replacement (#7706)
Replace the num_views for OpenGL multiviwe only when
- The engine is initialized with multiview stereo
- The variant for the material contains STE flag
- The program is for surface
- It's vertex shader (this is already in)
2024-03-26 21:36:22 +00:00
Powei Feng d70f2e1b81 vk: delete instead of ref-count EmptyTexture (#7711) 2024-03-26 13:35:50 -07:00
Powei Feng 2f359b73a4 Add missing include to Platform.h (#7709) 2024-03-26 19:51:57 +00:00
Sungun Park abb0cbc98e Add FILAMENT_ENABLE_MULTIVIEW option (#7707)
This allows the engine to include multiview shader code for default
materials.
2024-03-25 21:43:04 +00:00
Jacob Su 2763931b47 fix install android samples apk error. (#7230) 2024-03-22 23:05:01 -07:00
Sungun Park 0ead96b606 Replace value of num_views with engine's eye count (#7696)
For OpenGL multiview, it honors the qualifier `layout(num_views = X)`
specified in shader files to determine the number of views for
multiview.

We cannot recompile materials everytime the value changes. So replace
the value of num_views with the engine's eye count when shaders compile.
2024-03-22 21:45:58 +00:00
Ben Doherty 317c1bb7ea Metal: track buffer allocations (#7556) 2024-03-22 12:47:56 -07:00
Ben Doherty 9aaaad9271 Improve Skybox eyeDirection precision (#7685) 2024-03-22 12:03:06 -07:00
Mathias Agopian d2ce714e73 fix use-after-free disable option 2024-03-22 11:27:30 -07:00
Mathias Agopian 8398175d9c Add an option to disable use-after-free checks in the backend
BUGS=330403836
2024-03-22 10:24:29 -07:00
Sungun Park 26258a4718 Facilitate four views for multiview (#7694)
This change allows the combine function for multiview to be able to
combine more than two views side-by-side.
2024-03-22 17:09:08 +00:00
Mathias Agopian 3644e7f808 Fixes IBL prefilter has floor and ceiling flipped
FIXES=[330603077]
2024-03-21 13:28:24 -07:00
Powei Feng 4d774820d9 gl: Don't reference swapchain obj on Web
Fixes #7693
2024-03-21 13:27:45 -07:00
Eliza Velasquez aad45d9119 Fix typo 2024-03-21 19:59:47 +00:00
Eliza Velasquez 5389b37002 Incorporate feedback 2024-03-21 19:59:47 +00:00
Eliza Velasquez d5fe9e236f Allow rendering thread to pause
This PR adds a new `pause()` option to the `Engine` `Builder` and a new function
`setPaused()` to the `Engine`. While paused, the rendering thread will pause
indefinitely for commands as if none are available. As soon as the rendering
thread is unpaused, the commands are immediately executed.
2024-03-21 19:59:47 +00:00
Mathias Agopian 59890ac85a PlatformEGL::createSwapChain never returns a nullptr anymore
in case the swapchain creation fails, it will now return a swapchain
with an EGL_NO_SURFACE handle. this will avoid having to nullptr check
the pointer in various places and will revert to the previous behavior
on failure.

FIXES=[329659681]
2024-03-20 16:07:02 -07:00
Mathias Agopian 435969f565 attempt to detect buffer overflows in Texture::setImage()
We verify that the buffer given to setImage() is at least as large
as needed for the given region to transfer; at least based on the
size given.

This might help catch b/330407429.

BUGS=330407429
2024-03-20 16:06:43 -07:00
Ben Doherty e3db39105f iOS: fix gltf-viewer crash while destruction ResourceLoader (#7684) 2024-03-19 16:14:45 -07:00
Powei Feng dfa821d351 vk: fix broken gltf renderings (#7680)
This is due to color attachments being set to store=discard when
they are multi-sampled. It's unclear why that condition exists. For
now, removing it will fix the rendering issues with transparent
object + MSAA. We'll keep it as such until an issue surfaces.

Fixes #7674
2024-03-19 22:38:52 +00:00
Powei Feng 1ab223c965 vk: minor fixes (#7682)
- Add description to a few debug options
- Set correct usage flag for blit-src/dest images
- Correctly initialize a debug-only field in VulkanProgram
2024-03-19 13:59:52 -07:00
Mathias Agopian 29bb60cd94 fix typo that caused a wrong assertion 2024-03-19 13:13:12 -07:00
Mathias Agopian 93b15dac87 The type of geometry of a renderable can now be specified
- dynamic (default) no restriction apply
- static bounds: bounds and world transform can't be changed
- static: additionaly morphing/skinning and vertex/index buffers are
  immutable.

This will allow some optimizations in the future. Currently, we just
store the type but don't do anything with it.
2024-03-19 11:12:25 -07:00
Romain Guy a8fda9b4d0 Make PBR Neutral invertible (#7677)
Based on model-viewer's change at
https://github.com/google/model-viewer/pull/4716
2024-03-19 11:11:44 -07:00
39 changed files with 462 additions and 86 deletions
+2 -2
View File
@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.51.1'
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.1'
pod 'Filament', '~> 1.51.0'
```
### Snapshots
@@ -104,6 +104,14 @@ Java_com_google_android_filament_RenderableManager_nBuilderGeometry__JIIJJIIII(J
(size_t) count);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderGeometryType(JNIEnv*, jclass,
jlong nativeBuilder, int type) {
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
builder->geometryType((RenderableManager::Builder::GeometryType)type);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderMaterial(JNIEnv*, jclass,
@@ -243,9 +243,11 @@ public class Engine {
/**
* Sets the initial paused state of the rendering thread.
*
* <p>Warning: This is an experimental API. See {@link Engine#setPaused(boolean)} for
* caveats.
*
* @param paused Whether to start the rendering thread paused.
* @return A reference to this Builder for chaining calls.
* @warning Experimental.
*/
public Builder paused(boolean paused) {
nSetBuilderPaused(mNativeBuilder, paused);
@@ -1209,7 +1211,16 @@ public class Engine {
/**
* Pause or resume the rendering thread.
* @warning Experimental.
*
* <p>Warning: This is an experimental API. In particular, note the following caveats.
*
* <ul><li>
* Buffer callbacks will never be called as long as the rendering thread is paused.
* Do not rely on a buffer callback to unpause the thread.
* </li><li>
* While the rendering thread is paused, rendering commands will continue to be queued until the
* buffer limit is reached. When the limit is reached, the program will abort.
* </li></ul>
*/
public void setPaused(boolean paused) {
nSetPaused(getNativeObject(), paused);
@@ -175,6 +175,32 @@ public class RenderableManager {
return this;
}
/**
* Type of geometry for a Renderable
*/
public enum GeometryType {
/** dynamic gemoetry has no restriction */
DYNAMIC,
/** bounds and world space transform are immutable */
STATIC_BOUNDS,
/** skinning/morphing not allowed and Vertex/IndexBuffer immutables */
STATIC
}
/**
* Specify whether this renderable has static bounds. In this context his means that
* the renderable's bounding box cannot change and that the renderable's transform is
* assumed immutable. Changing the renderable's transform via the TransformManager
* can lead to corrupted graphics. Note that skinning and morphing are not forbidden.
* Disabled by default.
* @param enable whether this renderable has static bounds. false by default.
*/
@NonNull
public Builder geometryType(GeometryType type) {
nBuilderGeometryType(mNativeBuilder, type.ordinal());
return this;
}
/**
* Binds a material instance to the specified primitive.
*
@@ -964,6 +990,7 @@ public class RenderableManager {
private static native void nBuilderGeometry(long nativeBuilder, int index, int value, long nativeVertexBuffer, long nativeIndexBuffer);
private static native void nBuilderGeometry(long nativeBuilder, int index, int value, long nativeVertexBuffer, long nativeIndexBuffer, int offset, int count);
private static native void nBuilderGeometry(long nativeBuilder, int index, int value, long nativeVertexBuffer, long nativeIndexBuffer, int offset, int minIndex, int maxIndex, int count);
private static native void nBuilderGeometryType(long nativeBuilder, int type);
private static native void nBuilderMaterial(long nativeBuilder, int index, long nativeMaterialInstance);
private static native void nBuilderBlendOrder(long nativeBuilder, int index, int blendOrder);
private static native void nBuilderGlobalBlendOrderEnabled(long nativeBuilder, int index, boolean enabled);
+1 -1
View File
@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.51.1
VERSION_NAME=1.51.0
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
+1 -1
View File
@@ -516,7 +516,7 @@ function build_android {
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
for sample in ${ANDROID_SAMPLES}; do
echo "Installing out/${sample}-debug.apk"
cp samples/${sample}/build/outputs/apk/debug/${sample}-debug-unsigned.apk \
cp samples/${sample}/build/outputs/apk/debug/${sample}-debug.apk \
../out/${sample}-debug.apk
done
fi
@@ -116,6 +116,8 @@ public:
Program& cacheId(uint64_t cacheId) noexcept;
Program& multiview(bool multiview) noexcept;
ShaderSource const& getShadersSource() const noexcept { return mShadersSource; }
ShaderSource& getShadersSource() noexcept { return mShadersSource; }
@@ -143,6 +145,8 @@ public:
uint64_t getCacheId() const noexcept { return mCacheId; }
bool isMultiview() const noexcept { return mMultiview; }
CompilerPriorityQueue getPriorityQueue() const noexcept { return mPriorityQueue; }
private:
@@ -158,6 +162,11 @@ private:
utils::FixedCapacityVector<std::pair<utils::CString, uint8_t>> mAttributes;
std::array<UniformInfo, Program::UNIFORM_BINDING_COUNT> mBindingUniformInfo;
CompilerPriorityQueue mPriorityQueue = CompilerPriorityQueue::HIGH;
// Indicates the current engine was initialized with multiview stereo, and the variant for this
// program contains STE flag. This will be referred later for the OpenGL shader compiler to
// determine whether shader code replacement for the num_views should be performed.
// This variable could be promoted as a more generic variable later if other similar needs occur.
bool mMultiview = false;
};
} // namespace filament::backend
@@ -58,6 +58,7 @@ void CommandBufferQueue::requestExit() {
}
void CommandBufferQueue::setPaused(bool paused) {
std::lock_guard<utils::Mutex> const lock(mLock);
if (paused) {
mPaused = true;
} else {
@@ -125,6 +126,9 @@ void CommandBufferQueue::flush() noexcept {
#endif
SYSTRACE_NAME("waiting: CircularBuffer::flush()");
ASSERT_POSTCONDITION(!mPaused,
"CommandStream is full, but since the rendering thread is paused, "
"the buffer cannot flush and we will deadlock. Instead, abort.");
mCondition.wait(lock, [this, requiredSize]() -> bool {
// TODO: on macOS, we need to call pumpEvents from time to time
return mFreeSpace >= requiredSize;
+5
View File
@@ -91,6 +91,11 @@ Program& Program::cacheId(uint64_t cacheId) noexcept {
return *this;
}
Program& Program::multiview(bool multiview) noexcept {
mMultiview = multiview;
return *this;
}
io::ostream& operator<<(io::ostream& out, const Program& builder) {
out << "Program{";
builder.mLogger(out);
+3 -1
View File
@@ -2472,7 +2472,9 @@ void OpenGLDriver::setTextureData(GLTexture* t, uint32_t level,
size_t const stride = p.stride ? p.stride : width;
size_t const bpp = PBD::computeDataSize(p.format, p.type, 1, 1, 1);
size_t const bpr = PBD::computeDataSize(p.format, p.type, stride, 1, p.alignment);
void const* const buffer = static_cast<char const*>(p.buffer) + p.left * bpp + bpr * p.top;
size_t const bpl = bpr * height; // TODO: PBD should have a "layer stride"
void const* const buffer = static_cast<char const*>(p.buffer)
+ bpp* p.left + bpr * p.top + bpl * 0; // TODO: PBD should have a p.depth
switch (t->target) {
case SamplerType::SAMPLER_EXTERNAL:
@@ -30,6 +30,7 @@
#include <utils/Log.h>
#include <utils/Systrace.h>
#include <cctype>
#include <chrono>
#include <string>
#include <string_view>
@@ -264,6 +265,7 @@ ShaderCompilerService::program_token_t ShaderCompilerService::createProgram(
compileShaders(gl,
std::move(program.getShadersSource()),
program.getSpecializationConstants(),
program.isMultiview(),
shaders,
token->shaderSourceCode);
@@ -299,6 +301,7 @@ ShaderCompilerService::program_token_t ShaderCompilerService::createProgram(
compileShaders(gl,
std::move(program.getShadersSource()),
program.getSpecializationConstants(),
program.isMultiview(),
token->gl.shaders,
token->shaderSourceCode);
@@ -501,6 +504,7 @@ GLuint ShaderCompilerService::initialize(program_token_t& token) noexcept {
void ShaderCompilerService::compileShaders(OpenGLContext& context,
Program::ShaderSource shadersSource,
utils::FixedCapacityVector<Program::SpecializationConstant> const& specializationConstants,
bool multiview,
std::array<GLuint, Program::SHADER_TYPE_COUNT>& outShaders,
UTILS_UNUSED_IN_RELEASE std::array<CString, Program::SHADER_TYPE_COUNT>& outShaderSourceCode) noexcept {
@@ -514,8 +518,16 @@ void ShaderCompilerService::compileShaders(OpenGLContext& context,
};
std::string specializationConstantString;
int32_t numViews = 2;
for (auto const& sc : specializationConstants) {
appendSpecConstantString(specializationConstantString, sc);
if (sc.id == 8) {
// This constant must match
// ReservedSpecializationConstants::CONFIG_STEREO_EYE_COUNT
// which we can't use here because it's defined in EngineEnums.h.
// (we're breaking layering here, but it's for the good cause).
numViews = std::get<int32_t>(sc.value);
}
}
if (!specializationConstantString.empty()) {
specializationConstantString += '\n';
@@ -544,17 +556,23 @@ void ShaderCompilerService::compileShaders(OpenGLContext& context,
if (UTILS_LIKELY(!shadersSource[i].empty())) {
Program::ShaderBlob& shader = shadersSource[i];
char* shader_src = reinterpret_cast<char*>(shader.data());
size_t shader_len = shader.size();
// remove GOOGLE_cpp_style_line_directive
std::string_view const source = process_GOOGLE_cpp_style_line_directive(context,
reinterpret_cast<char*>(shader.data()), shader.size());
process_GOOGLE_cpp_style_line_directive(context, shader_src, shader_len);
// replace the value of layout(num_views = X) for multiview extension
if (multiview && stage == ShaderStage::VERTEX) {
process_OVR_multiview2(context, numViews, shader_src, shader_len);
}
// add support for ARB_shading_language_packing if needed
auto const packingFunctions = process_ARB_shading_language_packing(context);
// split shader source, so we can insert the specialization constants and the packing
// functions
auto const [prolog, body] = splitShaderSource(source);
auto const [prolog, body] = splitShaderSource({ shader_src, shader_len });
const std::array<const char*, 4> sources = {
prolog.data(),
@@ -577,7 +595,7 @@ void ShaderCompilerService::compileShaders(OpenGLContext& context,
#ifndef NDEBUG
// for debugging we return the original shader source (without the modifications we
// made here), otherwise the line numbers wouldn't match.
outShaderSourceCode[i] = { source.data(), source.length() };
outShaderSourceCode[i] = { shader_src, shader_len };
#endif
outShaders[i] = shaderId;
@@ -586,15 +604,59 @@ void ShaderCompilerService::compileShaders(OpenGLContext& context,
}
// If usages of the Google-style line directive are present, remove them, as some
// drivers don't allow the quotation marks. This happens in-place.
std::string_view ShaderCompilerService::process_GOOGLE_cpp_style_line_directive(OpenGLContext& context,
// drivers don't allow the quotation marks. This source modification happens in-place.
void ShaderCompilerService::process_GOOGLE_cpp_style_line_directive(OpenGLContext& context,
char* source, size_t len) noexcept {
if (!context.ext.GOOGLE_cpp_style_line_directive) {
if (UTILS_UNLIKELY(requestsGoogleLineDirectivesExtension({ source, len }))) {
removeGoogleLineDirectives(source, len); // length is unaffected
}
}
return { source, len };
}
// Look up the `source` to replace the number of eyes for multiview with the given number. This is
// necessary for OpenGL because OpenGL relies on the number specified in shader files to determine
// the number of views, which is assumed as a single digit, for multiview.
// This source modification happens in-place.
void ShaderCompilerService::process_OVR_multiview2(OpenGLContext& context,
int32_t eyeCount, char* source, size_t len) noexcept {
// We don't use regular expression in favor of performance.
if (context.ext.OVR_multiview2) {
const std::string_view shader{ source, len };
const std::string_view layout = "layout";
const std::string_view num_views = "num_views";
size_t found = 0;
while (true) {
found = shader.find(layout, found);
if (found == std::string_view::npos) {
break;
}
found = shader.find_first_not_of(' ', found + layout.size());
if (found == std::string_view::npos || shader[found] != '(') {
continue;
}
found = shader.find_first_not_of(' ', found + 1);
if (found == std::string_view::npos) {
continue;
}
if (shader.compare(found, num_views.size(), num_views) != 0) {
continue;
}
found = shader.find_first_not_of(' ', found + num_views.size());
if (found == std::string_view::npos || shader[found] != '=') {
continue;
}
found = shader.find_first_not_of(' ', found + 1);
if (found == std::string_view::npos) {
continue;
}
// We assume the value should be one-digit number.
assert_invariant(eyeCount < 10);
assert_invariant(!::isdigit(source[found + 1]));
source[found] = '0' + eyeCount;
break;
}
}
}
// Tragically, OpenGL 4.1 doesn't support unpackHalf2x16 (appeared in 4.2) and
@@ -134,10 +134,14 @@ private:
OpenGLContext& context,
Program::ShaderSource shadersSource,
utils::FixedCapacityVector<Program::SpecializationConstant> const& specializationConstants,
bool multiview,
std::array<GLuint, Program::SHADER_TYPE_COUNT>& outShaders,
std::array<utils::CString, Program::SHADER_TYPE_COUNT>& outShaderSourceCode) noexcept;
static std::string_view process_GOOGLE_cpp_style_line_directive(OpenGLContext& context,
static void process_GOOGLE_cpp_style_line_directive(OpenGLContext& context,
char* source, size_t len) noexcept;
static void process_OVR_multiview2(OpenGLContext& context, int32_t eyeCount,
char* source, size_t len) noexcept;
static std::string_view process_ARB_shading_language_packing(OpenGLContext& context) noexcept;
@@ -43,9 +43,12 @@
// Enables Android systrace
#define FVK_DEBUG_SYSTRACE 0x00000001
// Group markers are used to denote collection of GPU commands. It is typically at the granualarity
// of a renderpass.
#define FVK_DEBUG_GROUP_MARKERS 0x00000002
// Group markers are used to denote collections of GPU commands. It is typically at the
// granualarity of a renderpass. You can enable this along with FVK_DEBUG_DEBUG_UTILS to take
// advantage of vkCmdBegin/EndDebugUtilsLabelEXT. You can also just enable this with
// FVK_DEBUG_PRINT_GROUP_MARKERS to print the current marker to stdout.
#define FVK_DEBUG_GROUP_MARKERS 0x00000002
#define FVK_DEBUG_TEXTURE 0x00000004
#define FVK_DEBUG_LAYOUT_TRANSITION 0x00000008
#define FVK_DEBUG_COMMAND_BUFFER 0x00000010
@@ -63,9 +66,11 @@
// Enable the debug utils extension if it is available.
#define FVK_DEBUG_DEBUG_UTILS 0x00008000
// Use this to debug potential Handle/Resource leakage. It will print out reference counts for all
// the currently active resources.
#define FVK_DEBUG_RESOURCE_LEAK 0x00010000
// Usefaul default combinations
// Useful default combinations
#define FVK_DEBUG_EVERYTHING 0xFFFFFFFF
#define FVK_DEBUG_PERFORMANCE \
FVK_DEBUG_SYSTRACE
@@ -239,7 +239,7 @@ VkRenderPass VulkanFboCache::getRenderPass(RenderPassKey config) noexcept {
.format = config.colorFormat[i],
.samples = (VkSampleCountFlagBits) config.samples,
.loadOp = clear ? kClear : (discard ? kDontCare : kKeep),
.storeOp = config.samples == 1 ? kEnableStore : kDisableStore,
.storeOp = kEnableStore,
.stencilLoadOp = kDontCare,
.stencilStoreOp = kDisableStore,
.initialLayout = ((!discard && config.initialColorLayoutMask & (1 << i)) || clear)
+5 -1
View File
@@ -77,7 +77,11 @@ private:
struct PipelineInfo {
PipelineInfo()
: bindingToSamplerIndex(MAX_SAMPLER_COUNT, 0xffff) {}
: bindingToSamplerIndex(MAX_SAMPLER_COUNT, 0xffff)
#if FVK_ENABLED_DEBUG_SAMPLER_NAME
, bindingToName(MAX_SAMPLER_COUNT, "")
#endif
{}
// This bitset maps to each of the sampler in the sampler groups associated with this
// program, and whether each sampler is used in which shader (i.e. vert, frag, compute).
@@ -18,10 +18,10 @@
#include "VulkanTexture.h"
#include "VulkanUtility.h"
#include <DataReshaper.h>
#include <backend/DriverEnums.h>
#include <private/backend/BackendUtils.h>
#include "DataReshaper.h"
#include <utils/Panic.h>
using namespace bluevk;
@@ -100,9 +100,13 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice,
// Filament expects blit() to work with any texture, so we almost always set these usage flags.
// TODO: investigate performance implications of setting these flags.
const VkImageUsageFlags blittable = VK_IMAGE_USAGE_TRANSFER_DST_BIT |
constexpr VkImageUsageFlags blittable = VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
if (any(usage & (TextureUsage::BLIT_DST | TextureUsage::BLIT_SRC))) {
imageInfo.usage |= blittable;
}
if (any(usage & TextureUsage::SAMPLEABLE)) {
#if FVK_ENABLED(FVK_DEBUG_TEXTURE)
+12 -2
View File
@@ -408,9 +408,10 @@ public:
Builder& featureLevel(FeatureLevel featureLevel) noexcept;
/**
* Warning: This is an experimental API. See Engine::setPaused(bool) for caveats.
*
* @param paused Whether to start the rendering thread paused.
* @return A reference to this Builder for chaining calls.
* @warning Experimental.
*/
Builder& paused(bool paused) noexcept;
@@ -841,7 +842,16 @@ public:
/**
* Pause or resume rendering thread.
* @warning Experimental.
*
* <p>Warning: This is an experimental API. In particular, note the following caveats.
*
* <ul><li>
* Buffer callbacks will never be called as long as the rendering thread is paused.
* Do not rely on a buffer callback to unpause the thread.
* </li><li>
* While the rendering thread is paused, rendering commands will continue to be queued until the
* buffer limit is reached. When the limit is reached, the program will abort.
* </li></ul>
*/
void setPaused(bool paused);
+22 -1
View File
@@ -156,6 +156,15 @@ public:
*/
static constexpr uint8_t DEFAULT_CHANNEL = 2u;
/**
* Type of geometry for a Renderable
*/
enum class GeometryType : uint8_t {
DYNAMIC, //!< dynamic gemoetry has no restriction
STATIC_BOUNDS, //!< bounds and world space transform are immutable
STATIC //!< skinning/morphing not allowed and Vertex/IndexBuffer immutables
};
/**
* Creates a builder for renderable components.
*
@@ -204,6 +213,17 @@ public:
VertexBuffer* UTILS_NONNULL vertices,
IndexBuffer* UTILS_NONNULL indices) noexcept; //!< \overload
/**
* Specify the type of geometry for this renderable. DYNAMIC geometry has no restriction,
* STATIC_BOUNDS geometry means that both the bounds and the world-space transform of the
* 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.
*/
Builder& geometryType(GeometryType type) noexcept;
/**
* Binds a material instance to the specified primitive.
*
@@ -603,11 +623,12 @@ public:
/**
* Changes the bounding box used for frustum culling.
* The renderable must not have staticGeometry enabled.
*
* \see Builder::boundingBox()
* \see RenderableManager::getAxisAlignedBoundingBox()
*/
void setAxisAlignedBoundingBox(Instance instance, const Box& aabb) noexcept;
void setAxisAlignedBoundingBox(Instance instance, const Box& aabb);
/**
* Changes the visibility bits.
+15 -15
View File
@@ -3292,8 +3292,9 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::debugCombineArrayTexture(Fra
SamplerMagFilter filterMag,
SamplerMinFilter filterMin) noexcept {
assert_invariant(fg.getDescriptor(input).depth > 1);
assert_invariant(fg.getDescriptor(input).type == SamplerType::SAMPLER_2D_ARRAY);
auto& inputTextureDesc = fg.getDescriptor(input);
assert_invariant(inputTextureDesc.depth > 1);
assert_invariant(inputTextureDesc.type == SamplerType::SAMPLER_2D_ARRAY);
// TODO: add support for sub-resources
assert_invariant(fg.getSubResourceDescriptor(input).layer == 0);
@@ -3329,14 +3330,12 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::debugCombineArrayTexture(Fra
.filterMag = filterMag,
.filterMin = filterMin
});
mi->setParameter("layerIndex", 0);
mi->setParameter("viewport", float4{
float(vp.left) / inputDesc.width,
float(vp.bottom) / inputDesc.height,
float(vp.width) / inputDesc.width,
float(vp.height) / inputDesc.height
});
mi->commit(driver);
mi->use(driver);
auto pipeline = material.getPipelineState(mEngine);
@@ -3347,18 +3346,19 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::debugCombineArrayTexture(Fra
pipeline.first.rasterState.blendFunctionDstAlpha = BlendFunction::ONE_MINUS_SRC_ALPHA;
}
// Blit the scene rendered to the first layer to the left half of the screen.
out.params.viewport.width /= 2;
render(out, pipeline, driver);
// The width of each view takes up 1/depth of the screen width.
out.params.viewport.width /= inputTextureDesc.depth;
// Blit the scene rendered to the second layer to the right half of the screen.
// Don't clear or discard the target to keep the previously rendered left half image.
mi->setParameter("layerIndex", 1);
mi->commit(driver);
out.params.flags.clear = filament::backend::TargetBufferFlags::NONE;
out.params.flags.discardStart = filament::backend::TargetBufferFlags::NONE;
out.params.viewport.left += out.params.viewport.width;
render(out, pipeline, driver);
// Render all layers of the texture to the screen side-by-side.
for (uint32_t i = 0; i < inputTextureDesc.depth; ++i) {
mi->setParameter("layerIndex", i);
mi->commit(driver);
render(out, pipeline, driver);
// From the second draw, don't clear the targetbuffer.
out.params.flags.clear = filament::backend::TargetBufferFlags::NONE;
out.params.flags.discardStart = filament::backend::TargetBufferFlags::NONE;
out.params.viewport.left += out.params.viewport.width;
}
});
return ppQuadBlit->output;
+1 -1
View File
@@ -56,7 +56,7 @@ void RenderableManager::destroy(utils::Entity e) noexcept {
return downcast(this)->destroy(e);
}
void RenderableManager::setAxisAlignedBoundingBox(Instance instance, const Box& aabb) noexcept {
void RenderableManager::setAxisAlignedBoundingBox(Instance instance, const Box& aabb) {
downcast(this)->setAxisAlignedBoundingBox(instance, aabb);
}
+1 -1
View File
@@ -253,7 +253,7 @@ float3 PBRNeutralToneMapper::operator()(math::float3 color) const noexcept {
color *= newPeak / peak;
float g = 1.0f - 1.0f / (desaturation * (peak - newPeak) + 1.0f);
return mix(color, float3(1.0f), g);
return mix(color, float3(newPeak), g);
}
//------------------------------------------------------------------------------
+21 -1
View File
@@ -58,6 +58,7 @@ struct RenderableManager::BuilderDetails {
bool mScreenSpaceContactShadows : 1;
bool mSkinningBufferMode : 1;
bool mFogEnabled : 1;
RenderableManager::Builder::GeometryType mGeometryType : 2;
size_t mSkinningBoneCount = 0;
size_t mMorphTargetCount = 0;
Bone const* mUserBones = nullptr;
@@ -75,7 +76,9 @@ struct RenderableManager::BuilderDetails {
explicit BuilderDetails(size_t count)
: mEntries(count), mCulling(true), mCastShadows(false),
mReceiveShadows(true), mScreenSpaceContactShadows(false),
mSkinningBufferMode(false), mFogEnabled(true), mBonePairs() {
mSkinningBufferMode(false), mFogEnabled(true),
mGeometryType(RenderableManager::Builder::GeometryType::DYNAMIC),
mBonePairs() {
}
// this is only needed for the explicit instantiation below
BuilderDetails() = default;
@@ -121,6 +124,11 @@ RenderableManager::Builder& RenderableManager::Builder::geometry(size_t index,
return *this;
}
RenderableManager::Builder& RenderableManager::Builder::geometryType(GeometryType type) noexcept {
mImpl->mGeometryType = type;
return *this;
}
RenderableManager::Builder& RenderableManager::Builder::material(size_t index,
MaterialInstance const* materialInstance) noexcept {
if (index < mImpl->mEntries.size()) {
@@ -388,11 +396,21 @@ RenderableManager::Builder::Result RenderableManager::Builder::build(Engine& eng
ASSERT_PRECONDITION(mImpl->mSkinningBoneCount <= CONFIG_MAX_BONE_COUNT,
"bone count > %u", CONFIG_MAX_BONE_COUNT);
ASSERT_PRECONDITION(mImpl->mInstanceCount <= CONFIG_MAX_INSTANCES || !mImpl->mInstanceBuffer,
"instance count is %zu, but instance count is limited to CONFIG_MAX_INSTANCES (%zu) "
"instances when supplying transforms via an InstanceBuffer.",
mImpl->mInstanceCount,
CONFIG_MAX_INSTANCES);
if (mImpl->mGeometryType == GeometryType::STATIC) {
ASSERT_PRECONDITION(mImpl->mSkinningBoneCount > 0,
"Skinning can't be used with STATIC geometry");
ASSERT_PRECONDITION(mImpl->mMorphTargetCount > 0,
"Morphing can't be used with STATIC geometry");
}
if (mImpl->mInstanceBuffer) {
size_t const bufferInstanceCount = mImpl->mInstanceBuffer->mInstanceCount;
ASSERT_PRECONDITION(mImpl->mInstanceCount <= bufferInstanceCount,
@@ -519,6 +537,8 @@ void FRenderableManager::create(
setSkinning(ci, false);
setMorphing(ci, builder->mMorphTargetCount);
setFogEnabled(ci, builder->mFogEnabled);
// do this after calling setAxisAlignedBoundingBox
static_cast<Visibility&>(mManager[ci].visibility).geometryType = builder->mGeometryType;
mManager[ci].channels = builder->mLightChannels;
InstancesInfo& instances = manager[ci].instances;
+42 -15
View File
@@ -22,22 +22,30 @@
#include "HwRenderPrimitiveFactory.h"
#include "UniformBuffer.h"
#include "backend/DriverApiForward.h"
#include <backend/Handle.h>
#include <details/InstanceBuffer.h>
#include <filament/Box.h>
#include <filament/RenderableManager.h>
#include <details/InstanceBuffer.h>
#include <private/filament/UibStructs.h>
#include <backend/DriverApiForward.h>
#include <backend/Handle.h>
#include <utils/compiler.h>
#include <utils/Entity.h>
#include <utils/Panic.h>
#include <utils/SingleInstanceComponentManager.h>
#include <utils/Slice.h>
#include <utils/Range.h>
#include <math/mat4.h>
#include <algorithm>
#include <stddef.h>
#include <stdint.h>
namespace filament {
class FBufferObject;
@@ -49,9 +57,12 @@ class FSkinningBuffer;
class FVertexBuffer;
class FTexture;
class MorphTargetBuffer;
class FRenderableManager : public RenderableManager {
public:
using Instance = RenderableManager::Instance;
using GeometryType = RenderableManager::Builder::GeometryType;
// TODO: consider renaming, this pertains to material variants, not strictly visibility.
struct Visibility {
@@ -60,11 +71,13 @@ public:
bool castShadows : 1;
bool receiveShadows : 1;
bool culling : 1;
bool skinning : 1;
bool morphing : 1;
bool screenSpaceContactShadows : 1;
bool reversedWindingOrder : 1;
bool fog : 1;
GeometryType geometryType : 2;
};
static_assert(sizeof(Visibility) == sizeof(uint16_t), "Visibility should be 16 bits");
@@ -115,7 +128,7 @@ public:
void destroy(utils::Entity e) noexcept;
inline void setAxisAlignedBoundingBox(Instance instance, const Box& aabb) noexcept;
inline void setAxisAlignedBoundingBox(Instance instance, const Box& aabb);
inline void setLayerMask(Instance instance, uint8_t select, uint8_t values) noexcept;
@@ -136,13 +149,13 @@ public:
inline void setPrimitives(Instance instance, utils::Slice<FRenderPrimitive> const& primitives) noexcept;
inline void setSkinning(Instance instance, bool enable) noexcept;
inline void setSkinning(Instance instance, bool enable);
void setBones(Instance instance, Bone const* transforms, size_t boneCount, size_t offset = 0);
void setBones(Instance instance, math::mat4f const* transforms, size_t boneCount, size_t offset = 0);
void setSkinningBuffer(Instance instance, FSkinningBuffer* skinningBuffer,
size_t count, size_t offset);
inline void setMorphing(Instance instance, bool enable) noexcept;
inline void setMorphing(Instance instance, bool enable);
void setMorphWeights(Instance instance, float const* weights, size_t count, size_t offset);
void setMorphTargetBufferAt(Instance instance, uint8_t level, size_t primitiveIndex,
FMorphTargetBuffer* morphTargetBuffer, size_t offset, size_t count);
@@ -295,8 +308,12 @@ private:
FILAMENT_DOWNCAST(RenderableManager)
void FRenderableManager::setAxisAlignedBoundingBox(Instance instance, const Box& aabb) noexcept {
void FRenderableManager::setAxisAlignedBoundingBox(Instance instance, const Box& aabb) {
if (instance) {
ASSERT_PRECONDITION(
static_cast<Visibility const&>(
mManager[instance].visibility).geometryType == GeometryType::DYNAMIC,
"This renderable has staticBounds enabled; its AABB cannot change.");
mManager[instance].aabb = aabb;
}
}
@@ -368,16 +385,26 @@ bool FRenderableManager::getFogEnabled(RenderableManager::Instance instance) con
return getVisibility(instance).fog;
}
void FRenderableManager::setSkinning(Instance instance, bool enable) noexcept {
void FRenderableManager::setSkinning(Instance instance, bool enable) {
if (instance) {
Visibility& visibility = mManager[instance].visibility;
ASSERT_PRECONDITION(
visibility.geometryType != GeometryType::STATIC || !enable,
"Skinning can't be used with STATIC geometry");
visibility.skinning = enable;
}
}
void FRenderableManager::setMorphing(Instance instance, bool enable) noexcept {
void FRenderableManager::setMorphing(Instance instance, bool enable) {
if (instance) {
Visibility& visibility = mManager[instance].visibility;
ASSERT_PRECONDITION(
visibility.geometryType != GeometryType::STATIC || !enable,
"Morphing can't be used with STATIC geometry");
visibility.morphing = enable;
}
}
@@ -446,22 +473,22 @@ FRenderableManager::getInstancesInfo(Instance instance) const noexcept {
}
utils::Slice<FRenderPrimitive> const& FRenderableManager::getRenderPrimitives(
Instance instance, uint8_t level) const noexcept {
Instance instance, UTILS_UNUSED uint8_t level) const noexcept {
return mManager[instance].primitives;
}
utils::Slice<FRenderPrimitive>& FRenderableManager::getRenderPrimitives(
Instance instance, uint8_t level) noexcept {
Instance instance, UTILS_UNUSED uint8_t level) noexcept {
return mManager[instance].primitives;
}
utils::Slice<FRenderableManager::MorphTargets> const& FRenderableManager::getMorphTargets(
Instance instance, uint8_t level) const noexcept {
Instance instance, UTILS_UNUSED uint8_t level) const noexcept {
return mManager[instance].morphTargets;
}
utils::Slice<FRenderableManager::MorphTargets>& FRenderableManager::getMorphTargets(
Instance instance, uint8_t level) noexcept {
Instance instance, UTILS_UNUSED uint8_t level) noexcept {
return mManager[instance].morphTargets;
}
+3
View File
@@ -641,6 +641,9 @@ void FMaterial::getSurfaceProgramSlow(Variant variant,
Program pb{ getProgramWithVariants(variant, vertexVariant, fragmentVariant) };
pb.priorityQueue(priorityQueue);
pb.multiview(
mEngine.getConfig().stereoscopicType == StereoscopicType::MULTIVIEW &&
Variant::isStereoVariant(variant));
createAndCacheProgram(std::move(pb), variant);
}
+39 -7
View File
@@ -25,14 +25,33 @@
#include <filament/Texture.h>
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <ibl/Cubemap.h>
#include <ibl/CubemapIBL.h>
#include <ibl/CubemapUtils.h>
#include <ibl/Image.h>
#include <math/half.h>
#include <math/scalar.h>
#include <math/vec3.h>
#include <utils/Allocator.h>
#include <utils/algorithm.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/FixedCapacityVector.h>
#include <utils/Panic.h>
#include <algorithm>
#include <array>
#include <type_traits>
#include <utility>
#include <stddef.h>
#include <stdint.h>
using namespace utils;
namespace filament {
@@ -246,20 +265,20 @@ size_t FTexture::getDepth(size_t level) const noexcept {
void FTexture::setImage(FEngine& engine, size_t level,
uint32_t xoffset, uint32_t yoffset, uint32_t zoffset,
uint32_t width, uint32_t height, uint32_t depth,
FTexture::PixelBufferDescriptor&& buffer) const {
FTexture::PixelBufferDescriptor&& p) const {
if (UTILS_UNLIKELY(!engine.hasFeatureLevel(FeatureLevel::FEATURE_LEVEL_1))) {
ASSERT_PRECONDITION(buffer.stride == 0 || buffer.stride == width,
ASSERT_PRECONDITION(p.stride == 0 || p.stride == width,
"PixelBufferDescriptor stride must be 0 (or width) at FEATURE_LEVEL_0");
}
// this should have been validated already
assert_invariant(isTextureFormatSupported(engine, mFormat));
ASSERT_PRECONDITION(buffer.type == PixelDataType::COMPRESSED ||
validatePixelFormatAndType(mFormat, buffer.format, buffer.type),
ASSERT_PRECONDITION(p.type == PixelDataType::COMPRESSED ||
validatePixelFormatAndType(mFormat, p.format, p.type),
"The combination of internal format=%u and {format=%u, type=%u} is not supported.",
unsigned(mFormat), unsigned(buffer.format), unsigned(buffer.type));
unsigned(mFormat), unsigned(p.format), unsigned(p.type));
ASSERT_PRECONDITION(!mStream, "setImage() called on a Stream texture.");
@@ -283,7 +302,7 @@ void FTexture::setImage(FEngine& engine, size_t level,
unsigned(yoffset), unsigned(height), unsigned(valueForLevel(level, mHeight)),
unsigned(level));
ASSERT_PRECONDITION(buffer.buffer, "Data buffer is nullptr.");
ASSERT_PRECONDITION(p.buffer, "Data buffer is nullptr.");
uint32_t effectiveTextureDepthOrLayers;
switch (mTarget) {
@@ -311,8 +330,21 @@ void FTexture::setImage(FEngine& engine, size_t level,
"zoffset (%u) + depth (%u) > texture depth (%u) at level (%u)",
unsigned(zoffset), unsigned(depth), effectiveTextureDepthOrLayers, unsigned(level));
using PBD = PixelBufferDescriptor;
size_t const stride = p.stride ? p.stride : width;
size_t const bpp = PBD::computeDataSize(p.format, p.type, 1, 1, 1);
size_t const bpr = PBD::computeDataSize(p.format, p.type, stride, 1, p.alignment);
size_t const bpl = bpr * height; // TODO: PBD should have a "layer stride"
// TODO: PBD should have a p.depth (# layers to skip)
ASSERT_PRECONDITION(bpp * p.left + bpr * p.top + bpl * (0 + depth) <= p.size,
"buffer overflow: (size=%lu, stride=%lu, left=%u, top=%u) smaller than specified region "
"{{%u,%u,%u},{%u,%u,%u)}}",
size_t(p.size), size_t(p.stride), unsigned(p.left), unsigned(p.top),
unsigned(xoffset), unsigned(yoffset), unsigned(zoffset),
unsigned(width), unsigned(height), unsigned(depth));
engine.getDriverApi().update3DImage(mHandle,
uint8_t(level), xoffset, yoffset, zoffset, width, height, depth, std::move(buffer));
uint8_t(level), xoffset, yoffset, zoffset, width, height, depth, std::move(p));
}
// deprecated
+10 -1
View File
@@ -58,6 +58,15 @@ fragment {
vertex {
void materialVertex(inout MaterialVertexInputs material) {
material.eyeDirection.xyz = material.worldPosition.xyz;
// This code is taken from computeWorldPosition and assumes the vertex domain is 'device'.
vec4 p = getPosition();
// GL convention to inverted DX convention
p.z = p.z * -0.5 + 0.5;
vec4 worldPosition = getWorldFromClipMatrix() * p;
// Getting the true world position would require dividing by w, but since this is a skybox
// at inifinity, this results in very large numbers for material.eyeDirection.
// Since the eyeDirection is only used as a direction vector in the fragment shader, we can
// skip that step to improve precision.
material.eyeDirection.xyz = worldPosition.xyz;
}
}
+2 -2
View File
@@ -1,12 +1,12 @@
Pod::Spec.new do |spec|
spec.name = "Filament"
spec.version = "1.51.1"
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.1/filament-v1.51.1-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 = {
@@ -275,10 +275,6 @@ const float kSensitivity = 100.0f;
- (void)dealloc {
[self destroyModel];
delete _manipulator;
delete _stbDecoder;
delete _ktxDecoder;
_materialProvider->destroyMaterials();
delete _materialProvider;
auto* ncm = _assetLoader->getNames();
@@ -286,6 +282,10 @@ const float kSensitivity = 100.0f;
AssetLoader::destroy(&_assetLoader);
delete _resourceLoader;
delete _manipulator;
delete _stbDecoder;
delete _ktxDecoder;
_engine->destroy(_swapChain);
_engine->destroy(_view);
EntityManager::get().destroy(_entities.camera);
@@ -68,7 +68,7 @@ enum class ReservedSpecializationConstants : uint8_t {
CONFIG_POWER_VR_SHADER_WORKAROUNDS = 5,
CONFIG_DEBUG_DIRECTIONAL_SHADOWMAP = 6,
CONFIG_DEBUG_FROXEL_VISUALIZATION = 7,
CONFIG_STEREO_EYE_COUNT = 8,
CONFIG_STEREO_EYE_COUNT = 8, // don't change (hardcoded in ShaderCompilerService.cpp)
};
// This value is limited by UBO size, ES3.0 only guarantees 16 KiB.
+2 -2
View File
@@ -97,8 +97,8 @@ struct AssetConfiguration {
*
* // Load buffers and textures from disk.
* ResourceLoader resourceLoader({engine, ".", true});
* resourceLoader.addTextureProvider("image/png", decoder)
* resourceLoader.addTextureProvider("image/jpeg", decoder)
* resourceLoader.addTextureProvider("image/png", decoder);
* resourceLoader.addTextureProvider("image/jpeg", decoder);
* resourceLoader.loadResources(asset);
*
* // Free the glTF hierarchy as it is no longer needed.
+2 -1
View File
@@ -93,7 +93,8 @@ public:
/**
* Register a plugin that can consume PNG / JPEG content and produce filament::Texture objects.
*
* Destruction of the given provider is the client's responsibility.
* Destruction of the given provider is the client's responsibility and must be done after the
* destruction of this ResourceLoader.
*/
void addTextureProvider(const char* mimeType, TextureProvider* provider);
@@ -56,7 +56,7 @@ highp vec2 toEquirect(const highp vec3 s) {
highp float xf = atan(s.x, s.z) * (1.0 / PI); // range [-1.0, 1.0]
highp float yf = asin(s.y) * (2.0 / PI); // range [-1.0, 1.0]
xf = (xf + 1.0) * 0.5; // range [0, 1.0]
yf = (yf + 1.0) * 0.5; // range [0, 1.0]
yf = (1.0 - yf) * 0.5; // range [0, 1.0]
return vec2(xf, yf);
}
@@ -67,7 +67,9 @@ mediump vec3 sampleEquirect(mediump sampler2D equirect, const highp vec3 r) {
void postProcess(inout PostProcessInputs postProcess) {
highp vec2 uv = variable_vertex.xy; // interpolated at pixel's center
highp vec2 p = uv * 2.0 - 1.0;
highp vec2 p = vec2(
uv.x * 2.0 - 1.0,
1.0 - uv.y * 2.0);
float side = materialParams.side;
float mirror = materialParams.mirror;
+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
# ==================================================================================================
+16 -1
View File
@@ -258,6 +258,18 @@ public:
*/
virtual const char* what() const noexcept = 0;
/**
* 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 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
@@ -305,6 +317,8 @@ public:
const char* what() const noexcept override;
// 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;
@@ -369,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
+22 -4
View File
@@ -16,6 +16,10 @@
#include <utils/Panic.h>
#if defined(__APPLE__)
#include <utils/darwin/Exception.h>
#endif
#include <atomic>
#include <cstdarg>
#include <cstdlib>
@@ -88,6 +92,16 @@ const char* TPanic<T>::what() const noexcept {
return m_msg.c_str();
}
template<typename T>
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;
@@ -116,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
@@ -139,6 +152,11 @@ void TPanic<T>::panic(char const* function, char const* file, int line, const ch
va_end(args);
T e(function, formatFile(file), line, reason);
e.log();
#if defined(__APPLE__)
details::throwDarwinException(e);
#endif
#ifdef __EXCEPTIONS
throw e;
#endif
+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];
}
}
+4
View File
@@ -938,6 +938,10 @@ class_<RenderableBuilder>("RenderableManager$Builder")
size_t count), {
return &builder->geometry(index, type, vertices, indices, offset, minIndex, maxIndex, count); })
.BUILDER_FUNCTION("geometryType", RenderableBuilder, (RenderableBuilder* builder,
RenderableManager::Builder::GeometryType type), {
return &builder->geometryType(type); })
.BUILDER_FUNCTION("material", RenderableBuilder, (RenderableBuilder* builder,
size_t index, MaterialInstance* mi), {
return &builder->material(index, mi); })
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "filament",
"version": "1.51.1",
"version": "1.51.0",
"description": "Real-time physically based rendering engine",
"main": "filament.js",
"module": "filament.js",