diff --git a/bullet3 b/bullet3 index 6bb8d112..e9c461b0 160000 --- a/bullet3 +++ b/bullet3 @@ -1 +1 @@ -Subproject commit 6bb8d1123d8a55d407b19fd3357c724d0f5c9d3c +Subproject commit e9c461b0ace140d5c73972760781d94b7b5eee53 diff --git a/filament b/filament index 3ca9b9cd..cab799f5 160000 --- a/filament +++ b/filament @@ -1 +1 @@ -Subproject commit 3ca9b9cd0fdb6435af3a084813edd6ead8abc2b8 +Subproject commit cab799f531ce2fe871083b201efa2c142ed0bbb5 diff --git a/package/android/libs/filament/include/backend/DriverEnums.h b/package/android/libs/filament/include/backend/DriverEnums.h index ef1c655c..d69a9991 100644 --- a/package/android/libs/filament/include/backend/DriverEnums.h +++ b/package/android/libs/filament/include/backend/DriverEnums.h @@ -22,14 +22,17 @@ #include #include // Because we define ERROR in the FenceStatus enum. +#include #include +#include #include #include #include // FIXME: STL headers are not allowed in public headers #include // FIXME: STL headers are not allowed in public headers +#include // FIXME: STL headers are not allowed in public headers #include #include @@ -90,12 +93,15 @@ static constexpr uint64_t SWAP_CHAIN_HAS_STENCIL_BUFFER = SWAP_CHAIN_CON */ static constexpr uint64_t SWAP_CHAIN_CONFIG_PROTECTED_CONTENT = 0x40; - static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES. static constexpr size_t MAX_SAMPLER_COUNT = 62; // Maximum needed at feature level 3. static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects. static constexpr size_t MAX_SSBO_COUNT = 4; // This is guaranteed by OpenGL ES. +static constexpr size_t MAX_PUSH_CONSTANT_COUNT = 32; // Vulkan 1.1 spec allows for 128-byte + // of push constant (we assume 4-byte + // types). + // Per feature level caps // Use (int)FeatureLevel to index this array static constexpr struct { @@ -112,7 +118,7 @@ static_assert(MAX_VERTEX_BUFFER_COUNT <= MAX_VERTEX_ATTRIBUTE_COUNT, "The number of buffer objects that can be attached to a VertexBuffer must be " "less than or equal to the maximum number of vertex attributes."); -static constexpr size_t CONFIG_UNIFORM_BINDING_COUNT = 10; // This is guaranteed by OpenGL ES. +static constexpr size_t CONFIG_UNIFORM_BINDING_COUNT = 9; // This is guaranteed by OpenGL ES. static constexpr size_t CONFIG_SAMPLER_BINDING_COUNT = 4; // This is guaranteed by OpenGL ES. /** @@ -331,7 +337,7 @@ enum class UniformType : uint8_t { /** * Supported constant parameter types */ - enum class ConstantType : uint8_t { +enum class ConstantType : uint8_t { INT, FLOAT, BOOL @@ -686,7 +692,7 @@ enum class TextureUsage : uint16_t { SUBPASS_INPUT = 0x0020, //!< Texture can be used as a subpass input BLIT_SRC = 0x0040, //!< Texture can be used the source of a blit() BLIT_DST = 0x0080, //!< Texture can be used the destination of a blit() - PROTECTED = 0x0100, //!< Texture can be used the destination of a blit() + PROTECTED = 0x0100, //!< Texture can be used for protected content DEFAULT = UPLOADABLE | SAMPLEABLE //!< Default texture usage }; @@ -1218,13 +1224,15 @@ struct StencilState { uint8_t padding = 0; }; +using PushConstantVariant = std::variant; + static_assert(sizeof(StencilState::StencilOperations) == 5u, "StencilOperations size not what was intended"); static_assert(sizeof(StencilState) == 12u, "StencilState size not what was intended"); -using FrameScheduledCallback = void(*)(PresentCallable callable, void* user); +using FrameScheduledCallback = utils::Invocable; enum class Workaround : uint16_t { // The EASU pass must split because shader compiler flattens early-exit branch @@ -1243,13 +1251,7 @@ enum class Workaround : uint16_t { POWER_VR_SHADER_WORKAROUNDS, }; -//! The type of technique for stereoscopic rendering -enum class StereoscopicType : uint8_t { - // Stereoscopic rendering is performed using instanced rendering technique. - INSTANCED, - // Stereoscopic rendering is performed using the multiview feature from the graphics backend. - MULTIVIEW, -}; +using StereoscopicType = backend::Platform::StereoscopicType; } // namespace filament::backend diff --git a/package/android/libs/filament/include/backend/Handle.h b/package/android/libs/filament/include/backend/Handle.h index 4b63607a..c54e9609 100644 --- a/package/android/libs/filament/include/backend/Handle.h +++ b/package/android/libs/filament/include/backend/Handle.h @@ -75,6 +75,19 @@ class HandleBase { HandleBase(HandleBase const& rhs) noexcept = default; HandleBase& operator=(HandleBase const& rhs) noexcept = default; + HandleBase(HandleBase&& rhs) noexcept + : object(rhs.object) { + rhs.object = nullid; + } + + HandleBase& operator=(HandleBase&& rhs) noexcept { + if (this != &rhs) { + object = rhs.object; + rhs.object = nullid; + } + return *this; + } + private: HandleId object; }; @@ -89,8 +102,10 @@ struct Handle : public HandleBase { Handle() noexcept = default; Handle(Handle const& rhs) noexcept = default; + Handle(Handle&& rhs) noexcept = default; Handle& operator=(Handle const& rhs) noexcept = default; + Handle& operator=(Handle&& rhs) noexcept = default; explicit Handle(HandleId id) noexcept : HandleBase(id) { } diff --git a/package/android/libs/filament/include/backend/Platform.h b/package/android/libs/filament/include/backend/Platform.h index 03026dff..4f73c437 100644 --- a/package/android/libs/filament/include/backend/Platform.h +++ b/package/android/libs/filament/include/backend/Platform.h @@ -41,6 +41,26 @@ class UTILS_PUBLIC Platform { struct Fence {}; struct Stream {}; + /** + * The type of technique for stereoscopic rendering. (Note that the materials used will need to + * be compatible with the chosen technique.) + */ + enum class StereoscopicType : uint8_t { + /** + * No stereoscopic rendering + */ + NONE, + /** + * Stereoscopic rendering is performed using instanced rendering technique. + */ + INSTANCED, + /** + * Stereoscopic rendering is performed using the multiview feature from the graphics + * backend. + */ + MULTIVIEW, + }; + struct DriverConfig { /** * Size of handle arena in bytes. Setting to 0 indicates default value is to be used. @@ -65,6 +85,17 @@ class UTILS_PUBLIC Platform { * Disable backend handles use-after-free checks. */ bool disableHandleUseAfterFreeCheck = false; + + /** + * Force GLES2 context if supported, or pretend the context is ES2. Only meaningful on + * GLES 3.x backends. + */ + bool forceGLES2Context = false; + + /** + * Sets the technique for stereoscopic rendering. + */ + StereoscopicType stereoscopicType = StereoscopicType::NONE; }; Platform() noexcept; diff --git a/package/android/libs/filament/include/backend/PresentCallable.h b/package/android/libs/filament/include/backend/PresentCallable.h index 4402f222..f37d7704 100644 --- a/package/android/libs/filament/include/backend/PresentCallable.h +++ b/package/android/libs/filament/include/backend/PresentCallable.h @@ -48,7 +48,7 @@ namespace filament::backend { * and optional user data: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * swapChain->setFrameScheduledCallback(myFrameScheduledCallback, nullptr); + * swapChain->setFrameScheduledCallback(nullptr, myFrameScheduledCallback); * if (renderer->beginFrame(swapChain)) { * renderer->render(view); * renderer->endFrame(); @@ -58,8 +58,6 @@ namespace filament::backend { * @remark Only Filament's Metal backend supports PresentCallables and frame callbacks. Other * backends ignore the callback (which will never be called) and proceed normally. * - * @remark The SwapChain::FrameScheduledCallback is called on an arbitrary thread. - * * Applications *must* call each PresentCallable they receive. Each PresentCallable represents a * frame that is waiting to be presented. If an application fails to call a PresentCallable, a * memory leak could occur. To "cancel" the presentation of a frame, pass false to the diff --git a/package/android/libs/filament/include/backend/Program.h b/package/android/libs/filament/include/backend/Program.h index fe1c4a9b..7cec72cd 100644 --- a/package/android/libs/filament/include/backend/Program.h +++ b/package/android/libs/filament/include/backend/Program.h @@ -84,6 +84,9 @@ class Program { // null terminating character. Program& shader(ShaderStage shader, void const* data, size_t size); + // sets the language of the shader sources provided with shader() (defaults to ESSL3) + Program& shaderLanguage(ShaderLanguage shaderLanguage); + // Note: This is only needed for GLES3.0 backends, because the layout(binding=) syntax is // not permitted in glsl. The backend needs a way to associate a uniform block // to a binding point. @@ -114,6 +117,14 @@ class Program { Program& specializationConstants( utils::FixedCapacityVector specConstants) noexcept; + struct PushConstant { + utils::CString name; + ConstantType type; + }; + + Program& pushConstants(ShaderStage stage, + utils::FixedCapacityVector constants) noexcept; + Program& cacheId(uint64_t cacheId) noexcept; Program& multiview(bool multiview) noexcept; @@ -136,6 +147,8 @@ class Program { utils::CString const& getName() const noexcept { return mName; } utils::CString& getName() noexcept { return mName; } + auto const& getShaderLanguage() const { return mShaderLanguage; } + utils::FixedCapacityVector const& getSpecializationConstants() const noexcept { return mSpecializationConstants; } @@ -143,6 +156,15 @@ class Program { return mSpecializationConstants; } + utils::FixedCapacityVector const& getPushConstants( + ShaderStage stage) const noexcept { + return mPushConstants[static_cast(stage)]; + } + + utils::FixedCapacityVector& getPushConstants(ShaderStage stage) noexcept { + return mPushConstants[static_cast(stage)]; + } + uint64_t getCacheId() const noexcept { return mCacheId; } bool isMultiview() const noexcept { return mMultiview; } @@ -155,10 +177,12 @@ class Program { UniformBlockInfo mUniformBlocks = {}; SamplerGroupInfo mSamplerGroups = {}; ShaderSource mShadersSource; + ShaderLanguage mShaderLanguage = ShaderLanguage::ESSL3; utils::CString mName; uint64_t mCacheId{}; utils::Invocable mLogger; utils::FixedCapacityVector mSpecializationConstants; + std::array, SHADER_TYPE_COUNT> mPushConstants; utils::FixedCapacityVector> mAttributes; std::array mBindingUniformInfo; CompilerPriorityQueue mPriorityQueue = CompilerPriorityQueue::HIGH; diff --git a/package/android/libs/filament/include/backend/TargetBufferInfo.h b/package/android/libs/filament/include/backend/TargetBufferInfo.h index ce23fc5f..c4d284cc 100644 --- a/package/android/libs/filament/include/backend/TargetBufferInfo.h +++ b/package/android/libs/filament/include/backend/TargetBufferInfo.h @@ -29,17 +29,36 @@ namespace filament::backend { //! \privatesection struct TargetBufferInfo { + // note: the parameters of this constructor are not in the order of this structure's fields + TargetBufferInfo(Handle handle, uint8_t level, uint16_t layer, uint8_t baseViewIndex) noexcept + : handle(handle), baseViewIndex(baseViewIndex), level(level), layer(layer) { + } + + TargetBufferInfo(Handle handle, uint8_t level, uint16_t layer) noexcept + : handle(handle), level(level), layer(layer) { + } + + TargetBufferInfo(Handle handle, uint8_t level) noexcept + : handle(handle), level(level) { + } + + TargetBufferInfo(Handle handle) noexcept // NOLINT(*-explicit-constructor) + : handle(handle) { + } + + TargetBufferInfo() noexcept = default; + // texture to be used as render target Handle handle; - // starting layer index for multiview. This value is only used when the `layerCount` for the + // Starting layer index for multiview. This value is only used when the `layerCount` for the // render target is greater than 1. uint8_t baseViewIndex = 0; // level to be used uint8_t level = 0; - // for cubemaps and 3D textures. See TextureCubemapFace for the face->layer mapping + // For cubemaps and 3D textures. See TextureCubemapFace for the face->layer mapping uint16_t layer = 0; }; @@ -64,7 +83,7 @@ class MRT { MRT() noexcept = default; - MRT(TargetBufferInfo const& color) noexcept // NOLINT(hicpp-explicit-conversions) + MRT(TargetBufferInfo const& color) noexcept // NOLINT(hicpp-explicit-conversions, *-explicit-constructor) : mInfos{ color } { } @@ -84,7 +103,7 @@ class MRT { // this is here for backward compatibility MRT(Handle handle, uint8_t level, uint16_t layer) noexcept - : mInfos{{ handle, 0, level, layer }} { + : mInfos{{ handle, level, layer, 0 }} { } }; diff --git a/package/android/libs/filament/include/backend/platforms/OpenGLPlatform.h b/package/android/libs/filament/include/backend/platforms/OpenGLPlatform.h index dec6f47b..e00930c9 100644 --- a/package/android/libs/filament/include/backend/platforms/OpenGLPlatform.h +++ b/package/android/libs/filament/include/backend/platforms/OpenGLPlatform.h @@ -140,6 +140,23 @@ class OpenGLPlatform : public Platform { */ virtual uint32_t getDefaultFramebufferObject() noexcept; + /** + * Called by the backend when a frame starts. + * @param steady_clock_ns vsync time point on the monotonic clock + * @param refreshIntervalNs refresh interval in nanosecond + * @param frameId a frame id + */ + virtual void beginFrame( + int64_t monotonic_clock_ns, + int64_t refreshIntervalNs, + uint32_t frameId) noexcept; + + /** + * Called by the backend when a frame ends. + * @param frameId the frame id used in beginFrame + */ + virtual void endFrame( + uint32_t frameId) noexcept; /** * Type of contexts available @@ -191,6 +208,12 @@ class OpenGLPlatform : public Platform { utils::Invocable preContextChange, utils::Invocable postContextChange) noexcept; + /** + * Called by the backend just before calling commit() + * @see commit() + */ + virtual void preCommit() noexcept; + /** * Called by the driver once the current frame finishes drawing. Typically, this should present * the drawSwapChain. This is for example where `eglMakeCurrent()` would be called. diff --git a/package/android/libs/filament/include/backend/platforms/PlatformEGLAndroid.h b/package/android/libs/filament/include/backend/platforms/PlatformEGLAndroid.h index 32f83038..c3cc7da8 100644 --- a/package/android/libs/filament/include/backend/platforms/PlatformEGLAndroid.h +++ b/package/android/libs/filament/include/backend/platforms/PlatformEGLAndroid.h @@ -22,6 +22,10 @@ #include #include +#include + +#include + #include #include @@ -58,6 +62,13 @@ class PlatformEGLAndroid : public PlatformEGL { void terminate() noexcept override; + void beginFrame( + int64_t monotonic_clock_ns, + int64_t refreshIntervalNs, + uint32_t frameId) noexcept override; + + void preCommit() noexcept override; + /** * Set the presentation time using `eglPresentationTimeANDROID` * @param presentationTimeInNanosecond @@ -79,8 +90,18 @@ class PlatformEGLAndroid : public PlatformEGL { AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept override; private: + struct InitializeJvmForPerformanceManagerIfNeeded { + InitializeJvmForPerformanceManagerIfNeeded(); + }; + int mOSVersion; ExternalStreamManagerAndroid& mExternalStreamManager; + InitializeJvmForPerformanceManagerIfNeeded const mInitializeJvmForPerformanceManagerIfNeeded; + utils::PerformanceHintManager mPerformanceHintManager; + utils::PerformanceHintManager::Session mPerformanceHintSession; + + using clock = std::chrono::high_resolution_clock; + clock::time_point mStartTimeOfActualWork; }; } // namespace filament::backend diff --git a/package/android/libs/filament/include/backend/platforms/VulkanPlatform.h b/package/android/libs/filament/include/backend/platforms/VulkanPlatform.h index 6201d644..2bbe1983 100644 --- a/package/android/libs/filament/include/backend/platforms/VulkanPlatform.h +++ b/package/android/libs/filament/include/backend/platforms/VulkanPlatform.h @@ -23,9 +23,9 @@ #include #include +#include #include -#include #include #include @@ -47,6 +47,14 @@ struct VulkanPlatformPrivate; class VulkanPlatform : public Platform, utils::PrivateImplementation { public: + struct ExtensionHashFn { + std::size_t operator()(utils::CString const& s) const noexcept { + return std::hash{}(s.data()); + } + }; + // Utility for managing device or instance extensions during initialization. + using ExtensionSet = std::unordered_set; + /** * A collection of handles to objects and metadata that comprises a Vulkan context. The client * can instantiate this struct and pass to Engine::Builder::sharedContext if they wishes to @@ -82,6 +90,20 @@ class VulkanPlatform : public Platform, utils::PrivateImplementation explicitImageReadyWait = nullptr; + }; + VulkanPlatform(); ~VulkanPlatform() override; @@ -119,6 +141,12 @@ class VulkanPlatform : public Platform, utils::PrivateImplementation; - static ExtensionSet getRequiredInstanceExtensions(); + static ExtensionSet getSwapchainInstanceExtensions(); + // Platform dependent helper methods using SurfaceBundle = std::tuple; static SurfaceBundle createVkSurfaceKHR(void* nativeWindow, VkInstance instance, uint64_t flags) noexcept; diff --git a/package/android/libs/filament/include/filamat/MaterialBuilder.h b/package/android/libs/filament/include/filamat/MaterialBuilder.h index 4b66965d..c3045b94 100644 --- a/package/android/libs/filament/include/filamat/MaterialBuilder.h +++ b/package/android/libs/filament/include/filamat/MaterialBuilder.h @@ -245,6 +245,7 @@ class UTILS_PUBLIC MaterialBuilder : public MaterialBuilderBase { using CullingMode = filament::backend::CullingMode; using FeatureLevel = filament::backend::FeatureLevel; using StereoscopicType = filament::backend::StereoscopicType; + using ShaderStage = filament::backend::ShaderStage; enum class VariableQualifier : uint8_t { OUT @@ -692,6 +693,12 @@ class UTILS_PUBLIC MaterialBuilder : public MaterialBuilderBase { } defaultValue; }; + struct PushConstant { + utils::CString name; + ConstantType type; + ShaderStage stage; + }; + static constexpr size_t MATERIAL_PROPERTIES_COUNT = filament::MATERIAL_PROPERTIES_COUNT; using Property = filament::Property; @@ -720,6 +727,7 @@ class UTILS_PUBLIC MaterialBuilder : public MaterialBuilderBase { using SubpassList = Parameter[MAX_SUBPASS_COUNT]; using BufferList = std::vector>; using ConstantList = std::vector; + using PushConstantList = std::vector; // returns the number of parameters declared in this material uint8_t getParameterCount() const noexcept { return mParameterCount; } @@ -763,6 +771,10 @@ class UTILS_PUBLIC MaterialBuilder : public MaterialBuilderBase { void prepareToBuild(MaterialInfo& info) noexcept; + // Initialize internal push constants that will both be written to the shaders and material + // chunks (like user-defined spec constants). + void initPushConstants() noexcept; + // Return true if the shader is syntactically and semantically valid. // This method finds all the properties defined in the fragment and // vertex shaders of the material. @@ -829,6 +841,7 @@ class UTILS_PUBLIC MaterialBuilder : public MaterialBuilderBase { PropertyList mProperties; ParameterList mParameters; ConstantList mConstants; + PushConstantList mPushConstants; SubpassList mSubpasses; VariableList mVariables; OutputList mOutputs; diff --git a/package/android/libs/filament/include/filament/Engine.h b/package/android/libs/filament/include/filament/Engine.h index b741d3ab..2aed8273 100644 --- a/package/android/libs/filament/include/filament/Engine.h +++ b/package/android/libs/filament/include/filament/Engine.h @@ -315,7 +315,7 @@ class UTILS_PUBLIC Engine { * * @see View::setStereoscopicOptions */ - StereoscopicType stereoscopicType = StereoscopicType::INSTANCED; + StereoscopicType stereoscopicType = StereoscopicType::NONE; /* * The number of eyes to render when stereoscopic rendering is enabled. Supported values are @@ -340,6 +340,35 @@ class UTILS_PUBLIC Engine { * Disable backend handles use-after-free checks. */ bool disableHandleUseAfterFreeCheck = false; + + /* + * Sets a preferred shader language for Filament to use. + * + * The Metal backend supports two shader languages: MSL (Metal Shading Language) and + * METAL_LIBRARY (precompiled .metallib). This option controls which shader language is + * used when materials contain both. + * + * By default, when preferredShaderLanguage is unset, Filament will prefer METAL_LIBRARY + * shaders if present within a material, falling back to MSL. Setting + * preferredShaderLanguage to ShaderLanguage::MSL will instead instruct Filament to check + * for the presence of MSL in a material first, falling back to METAL_LIBRARY if MSL is not + * present. + * + * When using a non-Metal backend, setting this has no effect. + */ + enum class ShaderLanguage { + DEFAULT = 0, + MSL = 1, + METAL_LIBRARY = 2, + }; + ShaderLanguage preferredShaderLanguage = ShaderLanguage::DEFAULT; + + /* + * When the OpenGL ES backend is used, setting this value to true will force a GLES2.0 + * context if supported by the Platform, or if not, will have the backend pretend + * it's a GLES2 context. Ignored on other backends. + */ + bool forceGLES2Context = false; }; @@ -800,24 +829,51 @@ class UTILS_PUBLIC Engine { bool destroy(const InstanceBuffer* UTILS_NULLABLE p); //!< Destroys an InstanceBuffer object. void destroy(utils::Entity e); //!< Destroys all filament-known components from this entity - bool isValid(const BufferObject* UTILS_NULLABLE p); //!< Tells whether a BufferObject object is valid - bool isValid(const VertexBuffer* UTILS_NULLABLE p); //!< Tells whether an VertexBuffer object is valid - bool isValid(const Fence* UTILS_NULLABLE p); //!< Tells whether a Fence object is valid - bool isValid(const IndexBuffer* UTILS_NULLABLE p); //!< Tells whether an IndexBuffer object is valid - bool isValid(const SkinningBuffer* UTILS_NULLABLE p); //!< Tells whether a SkinningBuffer object is valid - bool isValid(const MorphTargetBuffer* UTILS_NULLABLE p); //!< Tells whether a MorphTargetBuffer object is valid - bool isValid(const IndirectLight* UTILS_NULLABLE p); //!< Tells whether an IndirectLight object is valid - bool isValid(const Material* UTILS_NULLABLE p); //!< Tells whether an IndirectLight object is valid - bool isValid(const Renderer* UTILS_NULLABLE p); //!< Tells whether a Renderer object is valid - bool isValid(const Scene* UTILS_NULLABLE p); //!< Tells whether a Scene object is valid - bool isValid(const Skybox* UTILS_NULLABLE p); //!< Tells whether a SkyBox object is valid - bool isValid(const ColorGrading* UTILS_NULLABLE p); //!< Tells whether a ColorGrading object is valid - bool isValid(const SwapChain* UTILS_NULLABLE p); //!< Tells whether a SwapChain object is valid - bool isValid(const Stream* UTILS_NULLABLE p); //!< Tells whether a Stream object is valid - bool isValid(const Texture* UTILS_NULLABLE p); //!< Tells whether a Texture object is valid - bool isValid(const RenderTarget* UTILS_NULLABLE p); //!< Tells whether a RenderTarget object is valid - bool isValid(const View* UTILS_NULLABLE p); //!< Tells whether a View object is valid - bool isValid(const InstanceBuffer* UTILS_NULLABLE p); //!< Tells whether an InstanceBuffer object is valid + /** Tells whether a BufferObject object is valid */ + bool isValid(const BufferObject* UTILS_NULLABLE p) const; + /** Tells whether an VertexBuffer object is valid */ + bool isValid(const VertexBuffer* UTILS_NULLABLE p) const; + /** Tells whether a Fence object is valid */ + bool isValid(const Fence* UTILS_NULLABLE p) const; + /** Tells whether an IndexBuffer object is valid */ + bool isValid(const IndexBuffer* UTILS_NULLABLE p) const; + /** Tells whether a SkinningBuffer object is valid */ + bool isValid(const SkinningBuffer* UTILS_NULLABLE p) const; + /** Tells whether a MorphTargetBuffer object is valid */ + bool isValid(const MorphTargetBuffer* UTILS_NULLABLE p) const; + /** Tells whether an IndirectLight object is valid */ + bool isValid(const IndirectLight* UTILS_NULLABLE p) const; + /** Tells whether an Material object is valid */ + bool isValid(const Material* UTILS_NULLABLE p) const; + /** Tells whether an MaterialInstance object is valid. Use this if you already know + * which Material this MaterialInstance belongs to. DO NOT USE getMaterial(), this would + * defeat the purpose of validating the MaterialInstance. + */ + bool isValid(const Material* UTILS_NONNULL m, const MaterialInstance* UTILS_NULLABLE p) const; + /** Tells whether an MaterialInstance object is valid. Use this if the Material the + * MaterialInstance belongs to is not known. This method can be expensive. + */ + bool isValidExpensive(const MaterialInstance* UTILS_NULLABLE p) const; + /** Tells whether a Renderer object is valid */ + bool isValid(const Renderer* UTILS_NULLABLE p) const; + /** Tells whether a Scene object is valid */ + bool isValid(const Scene* UTILS_NULLABLE p) const; + /** Tells whether a SkyBox object is valid */ + bool isValid(const Skybox* UTILS_NULLABLE p) const; + /** Tells whether a ColorGrading object is valid */ + bool isValid(const ColorGrading* UTILS_NULLABLE p) const; + /** Tells whether a SwapChain object is valid */ + bool isValid(const SwapChain* UTILS_NULLABLE p) const; + /** Tells whether a Stream object is valid */ + bool isValid(const Stream* UTILS_NULLABLE p) const; + /** Tells whether a Texture object is valid */ + bool isValid(const Texture* UTILS_NULLABLE p) const; + /** Tells whether a RenderTarget object is valid */ + bool isValid(const RenderTarget* UTILS_NULLABLE p) const; + /** Tells whether a View object is valid */ + bool isValid(const View* UTILS_NULLABLE p) const; + /** Tells whether an InstanceBuffer object is valid */ + bool isValid(const InstanceBuffer* UTILS_NULLABLE p) const; /** * Kicks the hardware thread (e.g. the OpenGL, Vulkan or Metal thread) and blocks until @@ -840,6 +896,15 @@ class UTILS_PUBLIC Engine { */ void flush(); + /** + * Get paused state of rendering thread. + * + *

Warning: This is an experimental API. + * + * @see setPaused + */ + bool isPaused() const noexcept; + /** * Pause or resume rendering thread. * @@ -865,6 +930,14 @@ class UTILS_PUBLIC Engine { */ void pumpMessageQueues(); + /** + * Switch the command queue to unprotected mode. Protected mode can be activated via + * Renderer::beginFrame() using a protected SwapChain. + * @see Renderer + * @see SwapChain + */ + void unprotected() noexcept; + /** * Returns the default Material. * diff --git a/package/android/libs/filament/include/filament/MaterialChunkType.h b/package/android/libs/filament/include/filament/MaterialChunkType.h index c80ac7d8..4a4561c1 100644 --- a/package/android/libs/filament/include/filament/MaterialChunkType.h +++ b/package/android/libs/filament/include/filament/MaterialChunkType.h @@ -53,6 +53,7 @@ enum UTILS_PUBLIC ChunkType : uint64_t { MaterialAttributeInfo = charTo64bitNum("MAT_ATTR"), MaterialProperties = charTo64bitNum("MAT_PROP"), MaterialConstants = charTo64bitNum("MAT_CONS"), + MaterialPushConstants = charTo64bitNum("MAT_PCON"), MaterialName = charTo64bitNum("MAT_NAME"), MaterialVersion = charTo64bitNum("MAT_VERS"), diff --git a/package/android/libs/filament/include/filament/MaterialEnums.h b/package/android/libs/filament/include/filament/MaterialEnums.h index 9f348481..c15c6c45 100644 --- a/package/android/libs/filament/include/filament/MaterialEnums.h +++ b/package/android/libs/filament/include/filament/MaterialEnums.h @@ -28,7 +28,7 @@ namespace filament { // update this when a new version of filament wouldn't work with older materials -static constexpr size_t MATERIAL_VERSION = 51; +static constexpr size_t MATERIAL_VERSION = 53; /** * Supported shading models diff --git a/package/android/libs/filament/include/filament/MaterialInstance.h b/package/android/libs/filament/include/filament/MaterialInstance.h index 7252f9a4..2b8aaa9a 100644 --- a/package/android/libs/filament/include/filament/MaterialInstance.h +++ b/package/android/libs/filament/include/filament/MaterialInstance.h @@ -140,6 +140,7 @@ class UTILS_PUBLIC MaterialInstance : public FilamentAPI { * @param values Array of values to set to the named parameter array. * @param count Size of the array to set. * @throws utils::PreConditionPanic if name doesn't exist or no-op if exceptions are disabled. + * @see Material::hasParameter */ template> void setParameter(const char* UTILS_NONNULL name, size_t nameLength, @@ -237,9 +238,13 @@ class UTILS_PUBLIC MaterialInstance : public FilamentAPI { /** * Gets the value of a parameter by name. * + * Note: Only supports non-texture parameters such as numeric and math types. + * * @param name Name of the parameter as defined by Material. Cannot be nullptr. * @param nameLength Length in `char` of the name parameter. * @throws utils::PreConditionPanic if name doesn't exist or no-op if exceptions are disabled. + * + * @see Material::hasParameter */ template T getParameter(const char* UTILS_NONNULL name, size_t nameLength) const; diff --git a/package/android/libs/filament/include/filament/RenderableManager.h b/package/android/libs/filament/include/filament/RenderableManager.h index bb50b7d1..363ef2d7 100644 --- a/package/android/libs/filament/include/filament/RenderableManager.h +++ b/package/android/libs/filament/include/filament/RenderableManager.h @@ -464,15 +464,30 @@ class UTILS_PUBLIC RenderableManager : public FilamentAPI { Builder& boneIndicesAndWeights(size_t primitiveIndex, utils::FixedCapacityVector< utils::FixedCapacityVector> indicesAndWeightsVector) noexcept; + + /** + * Controls if the renderable has legacy vertex morphing targets, zero by default. This is + * required to enable GPU morphing. + * + * For legacy morphing, the attached VertexBuffer must provide data in the + * appropriate VertexAttribute slots (\c MORPH_POSITION_0 etc). Legacy morphing only + * supports up to 4 morph targets and will be deprecated in the future. Legacy morphing must + * be enabled on the material definition: either via the legacyMorphing material attribute + * or by calling filamat::MaterialBuilder::useLegacyMorphing(). + * + * See also RenderableManager::setMorphWeights(), which can be called on a per-frame basis + * to advance the animation. + */ + Builder& morphing(size_t targetCount) noexcept; + /** * Controls if the renderable has vertex morphing targets, zero by default. This is * required to enable GPU morphing. * * Filament supports two morphing modes: standard (default) and legacy. * - * For standard morphing, A MorphTargetBuffer must be created and provided via - * RenderableManager::setMorphTargetBufferAt(). Standard morphing supports up to - * \c CONFIG_MAX_MORPH_TARGET_COUNT morph targets. + * For standard morphing, A MorphTargetBuffer must be provided. + * Standard morphing supports up to \c CONFIG_MAX_MORPH_TARGET_COUNT morph targets. * * For legacy morphing, the attached VertexBuffer must provide data in the * appropriate VertexAttribute slots (\c MORPH_POSITION_0 etc). Legacy morphing only @@ -483,29 +498,35 @@ class UTILS_PUBLIC RenderableManager : public FilamentAPI { * See also RenderableManager::setMorphWeights(), which can be called on a per-frame basis * to advance the animation. */ - Builder& morphing(size_t targetCount) noexcept; + Builder& morphing(MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer) noexcept; /** - * Specifies the morph target buffer for a primitive. - * - * The morph target buffer must have an associated renderable and geometry. Two conditions - * must be met: - * 1. The number of morph targets in the buffer must equal the renderable's morph target - * count. - * 2. The vertex count of each morph target must equal the geometry's vertex count. + * @deprecated Use morphing(uint8_t level, size_t primitiveIndex, size_t offset, size_t count) instead + */ + Builder& morphing(uint8_t level, size_t primitiveIndex, + MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer, + size_t offset, size_t count) noexcept; + + /** + * @deprecated Use morphing(uint8_t level, size_t primitiveIndex, size_t offset, size_t count) instead + */ + inline Builder& morphing(uint8_t level, size_t primitiveIndex, + MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer) noexcept { + return morphing(level, primitiveIndex, morphTargetBuffer, 0, + morphTargetBuffer->getVertexCount()); + } + + /** + * Specifies the the range of the MorphTargetBuffer to use with this primitive. * * @param level the level of detail (lod), only 0 can be specified * @param primitiveIndex zero-based index of the primitive, must be less than the count passed to Builder constructor - * @param morphTargetBuffer specifies the morph target buffer * @param offset specifies where in the morph target buffer to start reading (expressed as a number of vertices) * @param count number of vertices in the morph target buffer to read, must equal the geometry's count (for triangles, this should be a multiple of 3) */ Builder& morphing(uint8_t level, size_t primitiveIndex, - MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer, size_t offset, size_t count) noexcept; - inline Builder& morphing(uint8_t level, size_t primitiveIndex, - MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer) noexcept; /** * Sets the drawing order for blended primitives. The drawing order is either global or @@ -765,14 +786,19 @@ class UTILS_PUBLIC RenderableManager : public FilamentAPI { /** * Associates a MorphTargetBuffer to the given primitive. */ + void setMorphTargetBufferAt(Instance instance, uint8_t level, size_t primitiveIndex, + size_t offset, size_t count); + + /** @deprecated */ void setMorphTargetBufferAt(Instance instance, uint8_t level, size_t primitiveIndex, MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer, size_t offset, size_t count); - /** - * Utility method to change a MorphTargetBuffer to the given primitive - */ + /** @deprecated */ inline void setMorphTargetBufferAt(Instance instance, uint8_t level, size_t primitiveIndex, - MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer); + MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer) { + setMorphTargetBufferAt(instance, level, primitiveIndex, morphTargetBuffer, 0, + morphTargetBuffer->getVertexCount()); + } /** * Get a MorphTargetBuffer to the given primitive or null if it doesn't exist. @@ -906,20 +932,6 @@ class UTILS_PUBLIC RenderableManager : public FilamentAPI { ~RenderableManager() = default; }; -RenderableManager::Builder& RenderableManager::Builder::morphing( - uint8_t level, size_t primitiveIndex, - MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer) noexcept { - return morphing(level, primitiveIndex, morphTargetBuffer, 0, - morphTargetBuffer->getVertexCount()); -} - -void RenderableManager::setMorphTargetBufferAt( - Instance instance, uint8_t level, size_t primitiveIndex, - MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer) { - setMorphTargetBufferAt(instance, level, primitiveIndex, morphTargetBuffer, 0, - morphTargetBuffer->getVertexCount()); -} - template Box RenderableManager::computeAABB( VECTOR const* UTILS_NONNULL vertices, diff --git a/package/android/libs/filament/include/filament/SwapChain.h b/package/android/libs/filament/include/filament/SwapChain.h index 0af01afc..6917507a 100644 --- a/package/android/libs/filament/include/filament/SwapChain.h +++ b/package/android/libs/filament/include/filament/SwapChain.h @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -115,7 +116,7 @@ class Engine; * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * SDL_SysWMinfo wmi; * SDL_VERSION(&wmi.version); - * ASSERT_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi), "SDL version unsupported!"); + * FILAMENT_CHECK_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi)) << "SDL version unsupported!"; * HDC nativeWindow = (HDC) wmi.info.win.hdc; * * using namespace filament; @@ -264,13 +265,22 @@ class UTILS_PUBLIC SwapChain : public FilamentAPI { * backend. * * A FrameScheduledCallback can be set on an individual SwapChain through - * SwapChain::setFrameScheduledCallback. If the callback is set, then the SwapChain will *not* - * automatically schedule itself for presentation. Instead, the application must call the - * PresentCallable passed to the FrameScheduledCallback. + * SwapChain::setFrameScheduledCallback. If the callback is set for a given frame, then the + * SwapChain will *not* automatically schedule itself for presentation. Instead, the application + * must call the PresentCallable passed to the FrameScheduledCallback. * - * There may be only one FrameScheduledCallback set per SwapChain. A call to - * SwapChain::setFrameScheduledCallback will overwrite any previous FrameScheduledCallbacks set - * on the same SwapChain. + * Each SwapChain can have only one FrameScheduledCallback set per frame. If + * setFrameScheduledCallback is called multiple times on the same SwapChain before + * Renderer::endFrame(), the most recent call effectively overwrites any previously set + * callback. This allows the callback to be updated as needed before the frame has finished + * encoding. + * + * The "last" callback set by setFrameScheduledCallback gets "latched" when Renderer::endFrame() + * is executed. At this point, the state of the callback is fixed and is the one used for the + * frame that was just encoded. Subsequent changes to the callback using + * setFrameScheduledCallback after endFrame() apply to the next frame. + * + * Use \c setFrameScheduledCallback() (with default arguments) to unset the callback. * * If your application delays the call to the PresentCallable by, for example, calling it on a * separate thread, you must ensure all PresentCallables have been called before shutting down @@ -278,28 +288,26 @@ class UTILS_PUBLIC SwapChain : public FilamentAPI { * Engine::shutdown. This is necessary to ensure the Filament Engine has had a chance to clean * up all memory related to frame presentation. * - * @param callback A callback, or nullptr to unset. - * @param user An optional pointer to user data passed to the callback function. + * @param handler Handler to dispatch the callback or nullptr for the default handler. + * @param callback Callback called when the frame is scheduled. * * @remark Only Filament's Metal backend supports PresentCallables and frame callbacks. Other * backends ignore the callback (which will never be called) and proceed normally. * - * @remark The SwapChain::FrameScheduledCallback is called on an arbitrary thread. - * + * @see CallbackHandler * @see PresentCallable */ - void setFrameScheduledCallback(FrameScheduledCallback UTILS_NULLABLE callback, - void* UTILS_NULLABLE user = nullptr); + void setFrameScheduledCallback(backend::CallbackHandler* UTILS_NULLABLE handler = nullptr, + FrameScheduledCallback&& callback = {}); /** - * Returns the SwapChain::FrameScheduledCallback that was previously set with - * SwapChain::setFrameScheduledCallback, or nullptr if one is not set. + * Returns whether or not this SwapChain currently has a FrameScheduledCallback set. * - * @return the previously-set FrameScheduledCallback, or nullptr + * @return true, if the last call to setFrameScheduledCallback set a callback * * @see SwapChain::setFrameCompletedCallback */ - UTILS_NULLABLE FrameScheduledCallback getFrameScheduledCallback() const noexcept; + bool isFrameScheduledCallbackSet() const noexcept; /** * FrameCompletedCallback is a callback function that notifies an application when a frame's diff --git a/package/android/libs/filament/include/filament/View.h b/package/android/libs/filament/include/filament/View.h index 3cdd527f..1a1ed96f 100644 --- a/package/android/libs/filament/include/filament/View.h +++ b/package/android/libs/filament/include/filament/View.h @@ -189,6 +189,13 @@ class UTILS_PUBLIC View : public FilamentAPI { */ void setCamera(Camera* UTILS_NONNULL camera) noexcept; + /** + * Returns whether a Camera is set. + * @return true if a camera is set. + * @see setCamera() + */ + bool hasCamera() const noexcept; + /** * Returns the Camera currently associated with this View. * @return A reference to the Camera associated to this View. diff --git a/package/android/libs/filament/include/gltfio/AssetLoader.h b/package/android/libs/filament/include/gltfio/AssetLoader.h index f516166a..bf650f69 100644 --- a/package/android/libs/filament/include/gltfio/AssetLoader.h +++ b/package/android/libs/filament/include/gltfio/AssetLoader.h @@ -38,6 +38,23 @@ namespace filament::gltfio { class NodeManager; +// Use this struct to enable mikktspace-based tangent-space computation. +/** + * \struct AssetConfigurationExtended AssetLoader.h gltfio/AssetLoader.h + * \brief extends struct AssetConfiguration + * Useful if client needs mikktspace tangent space computation. + * NOTE: Android, iOS, Web are not supported. And only disk-local glTF resources are supported. + */ +struct AssetConfigurationExtended { + //! Optional The same parameter as provided to \struct ResourceConfiguration ResourceLoader.h + //! gltfio/ResourceLoader.h + char const* gltfPath; + + //! Client can use this method to check if the extended implementation is supported on their + //! platform or not. + static bool isSupported(); +}; + /** * \struct AssetConfiguration AssetLoader.h gltfio/AssetLoader.h * \brief Construction parameters for AssetLoader. @@ -62,6 +79,10 @@ struct AssetConfiguration { //! Optional default node name for anonymous nodes char* defaultNodeName = nullptr; + + //! Optional to enable mikktspace tangents. Lifetime of struct only needs to be maintained for + // the duration of the constructor of AssetLoader. + AssetConfigurationExtended* ext = nullptr; }; /** diff --git a/package/android/libs/filament/include/utils/FixedCapacityVector.h b/package/android/libs/filament/include/utils/FixedCapacityVector.h index f3990124..1221e7cc 100644 --- a/package/android/libs/filament/include/utils/FixedCapacityVector.h +++ b/package/android/libs/filament/include/utils/FixedCapacityVector.h @@ -299,6 +299,16 @@ class UTILS_PUBLIC FixedCapacityVector { } } + UTILS_NOINLINE + void shrink_to_fit() { + if (size() < capacity()) { + FixedCapacityVector t(construct_with_capacity, size(), allocator()); + t.mSize = size(); + std::uninitialized_move(begin(), end(), t.begin()); + this->swap(t); + } + } + private: enum construct_with_capacity_tag{ construct_with_capacity }; @@ -318,9 +328,9 @@ class UTILS_PUBLIC FixedCapacityVector { iterator assertCapacityForSize(size_type s) { if constexpr(CapacityCheck || FILAMENT_FORCE_CAPACITY_CHECK) { - ASSERT_PRECONDITION(capacity() >= s, - "capacity exceeded: requested size %lu, available capacity %lu.", - (unsigned long)s, (unsigned long)capacity()); + FILAMENT_CHECK_PRECONDITION(capacity() >= s) + << "capacity exceeded: requested size " << (unsigned long)s + << "u, available capacity " << (unsigned long)capacity() << "u."; } return end(); } diff --git a/package/android/libs/filament/include/utils/Panic.h b/package/android/libs/filament/include/utils/Panic.h index c658da4b..6e9ac3f4 100644 --- a/package/android/libs/filament/include/utils/Panic.h +++ b/package/android/libs/filament/include/utils/Panic.h @@ -17,14 +17,28 @@ #ifndef TNT_UTILS_PANIC_H #define TNT_UTILS_PANIC_H +#ifdef FILAMENT_PANIC_USES_ABSL +# if FILAMENT_PANIC_USES_ABSL +# include "absl/log/log.h" +# define FILAMENT_CHECK_PRECONDITION CHECK +# define FILAMENT_CHECK_POSTCONDITION CHECK +# define FILAMENT_CHECK_ARITHMETIC CHECK +# endif +#endif + #include #include +#include #include +#include #ifdef __EXCEPTIONS # define UTILS_EXCEPTIONS 1 #else +# ifdef UTILS_EXCEPTIONS +# error UTILS_EXCEPTIONS is already defined! +# endif #endif /** @@ -280,12 +294,24 @@ class UTILS_PUBLIC Panic { */ virtual const char* what() const noexcept = 0; + /** + * Get the type of the panic (e.g. "Precondition") + * @return a C string containing the type of panic + */ + virtual const char* getType() const noexcept = 0; + /** * Get the reason string for the panic * @return a C string containing the reason for the panic */ virtual const char* getReason() const noexcept = 0; + /** + * Get a version of the reason string that is guaranteed to be constructed from literal + * strings only; it will contain no runtime information. + */ + virtual const char* getReasonLiteral() 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. @@ -334,7 +360,9 @@ class UTILS_PUBLIC TPanic : public Panic { const char* what() const noexcept override; // Panic interface + const char* getType() const noexcept override; const char* getReason() const noexcept override; + const char* getReasonLiteral() const noexcept override; const char* getFunction() const noexcept override; const char* getFile() const noexcept override; int getLine() const noexcept override; @@ -348,13 +376,14 @@ class UTILS_PUBLIC TPanic : public Panic { * @param function the name of the function where the error was detected * @param file the file where the above function in implemented * @param line the line in the above file where the error was detected + * @param literal a literal version of the error message * @param format printf style string describing the error * @see ASSERT_PRECONDITION, ASSERT_POSTCONDITION, ASSERT_ARITHMETIC * @see PANIC_PRECONDITION, PANIC_POSTCONDITION, PANIC_ARITHMETIC * @see setMode() */ - static void panic(char const* function, char const* file, int line, const char* format, ...) - UTILS_NORETURN; + static void panic(char const* function, char const* file, int line, char const* literal, + const char* format, ...) UTILS_NORETURN; /** * Depending on the mode set, either throws an exception of type T with the given reason plus @@ -363,43 +392,41 @@ class UTILS_PUBLIC TPanic : public Panic { * @param function the name of the function where the error was detected * @param file the file where the above function in implemented * @param line the line in the above file where the error was detected - * @param s std::string describing the error + * @param literal a literal version of the error message + * @param reason std::string describing the error * @see ASSERT_PRECONDITION, ASSERT_POSTCONDITION, ASSERT_ARITHMETIC * @see PANIC_PRECONDITION, PANIC_POSTCONDITION, PANIC_ARITHMETIC * @see setMode() */ - static inline void panic(char const* function, char const* file, int line, const std::string& s) - UTILS_NORETURN { - panic(function, file, line, s.c_str()); - } + static inline void panic( + char const* function, char const* file, int line, char const* literal, + std::string reason) UTILS_NORETURN; protected: - /** - * Creates a Panic. - * @param reason a description of the cause of the error - */ - explicit TPanic(std::string reason); /** * Creates a Panic with extra information about the error-site. * @param function the name of the function where the error was detected * @param file the file where the above function in implemented * @param line the line in the above file where the error was detected + * @param literal a literal version of the error message * @param reason a description of the cause of the error */ - TPanic(char const* function, char const* file, int line, std::string reason); + TPanic(char const* function, char const* file, int line, char const* literal, + std::string reason); ~TPanic() override; private: void buildMessage(); - CallStack m_callstack; - std::string m_reason; - char const* const m_function = nullptr; - char const* const m_file = nullptr; - const int m_line = -1; - mutable std::string m_msg; + char const* const mFile = nullptr; // file where the panic happened + char const* const mFunction = nullptr; // function where the panic happened + int const mLine = -1; // line where the panic happened + std::string mLiteral; // reason for the panic, built only from literals + std::string mReason; // reason for the panic + mutable std::string mWhat; // fully formatted reason + CallStack mCallstack; }; namespace details { @@ -421,6 +448,7 @@ class UTILS_PUBLIC PreconditionPanic : public TPanic { // e.g.: invalid arguments using TPanic::TPanic; friend class TPanic; + constexpr static auto type = "Precondition"; }; /** @@ -434,6 +462,7 @@ class UTILS_PUBLIC PostconditionPanic : public TPanic { // e.g.: dead-lock would occur, arithmetic errors using TPanic::TPanic; friend class TPanic; + constexpr static auto type = "Postcondition"; }; /** @@ -447,8 +476,74 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic { // e.g.: underflow, overflow, internal computations errors using TPanic::TPanic; friend class TPanic; + constexpr static auto type = "Arithmetic"; +}; + +namespace details { + +struct Voidify final { + template + void operator&&(const T&) const&& {} +}; + +class UTILS_PUBLIC PanicStream { +public: + PanicStream( + char const* function, + char const* file, + int line, + char const* message) noexcept; + + ~PanicStream(); + + PanicStream& operator<<(short value) noexcept; + PanicStream& operator<<(unsigned short value) noexcept; + + PanicStream& operator<<(char value) noexcept; + PanicStream& operator<<(unsigned char value) noexcept; + + PanicStream& operator<<(int value) noexcept; + PanicStream& operator<<(unsigned int value) noexcept; + + PanicStream& operator<<(long value) noexcept; + PanicStream& operator<<(unsigned long value) noexcept; + + PanicStream& operator<<(long long value) noexcept; + PanicStream& operator<<(unsigned long long value) noexcept; + + PanicStream& operator<<(float value) noexcept; + PanicStream& operator<<(double value) noexcept; + PanicStream& operator<<(long double value) noexcept; + + PanicStream& operator<<(bool value) noexcept; + + PanicStream& operator<<(const void* value) noexcept; + + PanicStream& operator<<(const char* string) noexcept; + PanicStream& operator<<(const unsigned char* string) noexcept; + + PanicStream& operator<<(std::string const& s) noexcept; + PanicStream& operator<<(std::string_view const& s) noexcept; + +protected: + io::sstream mStream; + char const* mFunction; + char const* mFile; + int mLine; + char const* mLiteral; }; +template +class TPanicStream : public PanicStream { +public: + using PanicStream::PanicStream; + ~TPanicStream() noexcept(false) UTILS_NORETURN { + T::panic(mFunction, mFile, mLine, mLiteral, mStream.c_str()); + } +}; + +} // namespace details + // ----------------------------------------------------------------------------------------------- } // namespace utils @@ -460,37 +555,70 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic { # define PANIC_FUNCTION __func__ #endif + +#define FILAMENT_CHECK_CONDITION_IMPL(cond) \ + switch (0) \ + case 0: \ + default: \ + UTILS_LIKELY(cond) ? (void)0 : ::utils::details::Voidify()&& + +#define FILAMENT_PANIC_IMPL(message, TYPE) \ + ::utils::details::TPanicStream<::utils::TYPE>(PANIC_FUNCTION, PANIC_FILE(__FILE__), __LINE__, message) + +#ifndef FILAMENT_CHECK_PRECONDITION +#define FILAMENT_CHECK_PRECONDITION(condition) \ + FILAMENT_CHECK_CONDITION_IMPL(condition) FILAMENT_PANIC_IMPL(#condition, PreconditionPanic) +#endif + +#ifndef FILAMENT_CHECK_POSTCONDITION +#define FILAMENT_CHECK_POSTCONDITION(condition) \ + FILAMENT_CHECK_CONDITION_IMPL(condition) FILAMENT_PANIC_IMPL(#condition, PostconditionPanic) +#endif + +#ifndef FILAMENT_CHECK_ARITHMETIC +#define FILAMENT_CHECK_ARITHMETIC(condition) \ + FILAMENT_CHECK_CONDITION_IMPL(condition) FILAMENT_PANIC_IMPL(#condition, ArithmeticPanic) +#endif + +#define PANIC_PRECONDITION_IMPL(cond, format, ...) \ + ::utils::PreconditionPanic::panic(PANIC_FUNCTION, \ + PANIC_FILE(__FILE__), __LINE__, #cond, format, ##__VA_ARGS__) + +#define PANIC_POSTCONDITION_IMPL(cond, format, ...) \ + ::utils::PostconditionPanic::panic(PANIC_FUNCTION, \ + PANIC_FILE(__FILE__), __LINE__, #cond, format, ##__VA_ARGS__) + +#define PANIC_ARITHMETIC_IMPL(cond, format, ...) \ + ::utils::ArithmeticPanic::panic(PANIC_FUNCTION, \ + PANIC_FILE(__FILE__), __LINE__, #cond, format, ##__VA_ARGS__) + +#define PANIC_LOG_IMPL(cond, format, ...) \ + ::utils::details::panicLog(PANIC_FUNCTION, \ + PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__) + /** * PANIC_PRECONDITION is a macro that reports a PreconditionPanic * @param format printf-style string describing the error in more details */ -#define PANIC_PRECONDITION(format, ...) \ - ::utils::PreconditionPanic::panic(PANIC_FUNCTION, \ - PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__) +#define PANIC_PRECONDITION(format, ...) PANIC_PRECONDITION_IMPL(format, format, ##__VA_ARGS__) /** * PANIC_POSTCONDITION is a macro that reports a PostconditionPanic * @param format printf-style string describing the error in more details */ -#define PANIC_POSTCONDITION(format, ...) \ - ::utils::PostconditionPanic::panic(PANIC_FUNCTION, \ - PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__) +#define PANIC_POSTCONDITION(format, ...) PANIC_POSTCONDITION_IMPL(format, format, ##__VA_ARGS__) /** * PANIC_ARITHMETIC is a macro that reports a ArithmeticPanic * @param format printf-style string describing the error in more details */ -#define PANIC_ARITHMETIC(format, ...) \ - ::utils::ArithmeticPanic::panic(PANIC_FUNCTION, \ - PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__) +#define PANIC_ARITHMETIC(format, ...) PANIC_ARITHMETIC_IMPL(format, format, ##__VA_ARGS__) /** * PANIC_LOG is a macro that logs a Panic, and continues as usual. * @param format printf-style string describing the error in more details */ -#define PANIC_LOG(format, ...) \ - ::utils::details::panicLog(PANIC_FUNCTION, \ - PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__) +#define PANIC_LOG(format, ...) PANIC_LOG_IMPL(format, format, ##__VA_ARGS__) /** * @ingroup errors @@ -501,14 +629,14 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic { * @param format printf-style string describing the error in more details */ #define ASSERT_PRECONDITION(cond, format, ...) \ - (!UTILS_LIKELY(cond) ? PANIC_PRECONDITION(format, ##__VA_ARGS__) : (void)0) + (!UTILS_LIKELY(cond) ? PANIC_PRECONDITION_IMPL(cond, format, ##__VA_ARGS__) : (void)0) #if defined(UTILS_EXCEPTIONS) || !defined(NDEBUG) #define ASSERT_PRECONDITION_NON_FATAL(cond, format, ...) \ - (!UTILS_LIKELY(cond) ? PANIC_PRECONDITION(format, ##__VA_ARGS__), false : true) + (!UTILS_LIKELY(cond) ? PANIC_PRECONDITION_IMPL(cond, format, ##__VA_ARGS__), false : true) #else #define ASSERT_PRECONDITION_NON_FATAL(cond, format, ...) \ - (!UTILS_LIKELY(cond) ? PANIC_LOG(format, ##__VA_ARGS__), false : true) + (!UTILS_LIKELY(cond) ? PANIC_LOG_IMPL(cond, format, ##__VA_ARGS__), false : true) #endif @@ -529,14 +657,14 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic { * @endcode */ #define ASSERT_POSTCONDITION(cond, format, ...) \ - (!UTILS_LIKELY(cond) ? PANIC_POSTCONDITION(format, ##__VA_ARGS__) : (void)0) + (!UTILS_LIKELY(cond) ? PANIC_POSTCONDITION_IMPL(cond, format, ##__VA_ARGS__) : (void)0) #if defined(UTILS_EXCEPTIONS) || !defined(NDEBUG) #define ASSERT_POSTCONDITION_NON_FATAL(cond, format, ...) \ - (!UTILS_LIKELY(cond) ? PANIC_POSTCONDITION(format, ##__VA_ARGS__), false : true) + (!UTILS_LIKELY(cond) ? PANIC_POSTCONDITION_IMPL(cond, format, ##__VA_ARGS__), false : true) #else #define ASSERT_POSTCONDITION_NON_FATAL(cond, format, ...) \ - (!UTILS_LIKELY(cond) ? PANIC_LOG(format, ##__VA_ARGS__), false : true) + (!UTILS_LIKELY(cond) ? PANIC_LOG_IMPL(cond, format, ##__VA_ARGS__), false : true) #endif /** @@ -557,14 +685,14 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic { * @endcode */ #define ASSERT_ARITHMETIC(cond, format, ...) \ - (!(cond) ? PANIC_ARITHMETIC(format, ##__VA_ARGS__) : (void)0) + (!(cond) ? PANIC_ARITHMETIC_IMPL(cond, format, ##__VA_ARGS__) : (void)0) #if defined(UTILS_EXCEPTIONS) || !defined(NDEBUG) #define ASSERT_ARITHMETIC_NON_FATAL(cond, format, ...) \ - (!UTILS_LIKELY(cond) ? PANIC_ARITHMETIC(format, ##__VA_ARGS__), false : true) + (!UTILS_LIKELY(cond) ? PANIC_ARITHMETIC_IMPL(cond, format, ##__VA_ARGS__), false : true) #else #define ASSERT_ARITHMETIC_NON_FATAL(cond, format, ...) \ - (!UTILS_LIKELY(cond) ? PANIC_LOG(format, ##__VA_ARGS__), false : true) + (!UTILS_LIKELY(cond) ? PANIC_LOG_IMPL(cond, format, ##__VA_ARGS__), false : true) #endif /** @@ -588,6 +716,7 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic { * } * @endcode */ -#define ASSERT_DESTRUCTOR(cond, format, ...) (!(cond) ? PANIC_LOG(format, ##__VA_ARGS__) : (void)0) +#define ASSERT_DESTRUCTOR(cond, format, ...) \ + (!UTILS_LIKELY(cond) ? PANIC_LOG_IMPL(cond, format, ##__VA_ARGS__) : (void)0) #endif // TNT_UTILS_PANIC_H diff --git a/package/android/libs/filament/include/utils/StructureOfArrays.h b/package/android/libs/filament/include/utils/StructureOfArrays.h index a4309584..c0b2315e 100644 --- a/package/android/libs/filament/include/utils/StructureOfArrays.h +++ b/package/android/libs/filament/include/utils/StructureOfArrays.h @@ -368,7 +368,7 @@ class StructureOfArraysBase { size_t last = mSize++; // Fold expression on the comma operator ([&]{ - new(std::get(mArrays) + last) Elements{std::get(args)}; + new(std::get(mArrays) + last) Elements{std::get(std::forward(args))}; }() , ...); } @@ -513,7 +513,7 @@ class StructureOfArraysBase { return (soa.elementAt(i) = other); } UTILS_ALWAYS_INLINE Type const& operator = (Type&& other) noexcept { - return (soa.elementAt(i) = other); + return (soa.elementAt(i) = std::forward(other)); } // comparisons UTILS_ALWAYS_INLINE bool operator==(Type const& other) const { diff --git a/package/android/libs/filament/include/utils/algorithm.h b/package/android/libs/filament/include/utils/algorithm.h index ea5ca44f..7a747b84 100644 --- a/package/android/libs/filament/include/utils/algorithm.h +++ b/package/android/libs/filament/include/utils/algorithm.h @@ -22,6 +22,7 @@ #include // for std::enable_if #include +#include #include namespace utils { @@ -43,9 +44,15 @@ constexpr inline T clz(T x) noexcept { static_assert(sizeof(T) * CHAR_BIT <= 128, "details::clz() only support up to 128 bits"); x |= (x >> 1u); x |= (x >> 2u); - x |= (x >> 4u); - x |= (x >> 8u); - x |= (x >> 16u); + if constexpr (sizeof(T) * CHAR_BIT >= 8) { // just to silence compiler warning + x |= (x >> 4u); + } + if constexpr (sizeof(T) * CHAR_BIT >= 16) { // just to silence compiler warning + x |= (x >> 8u); + } + if constexpr (sizeof(T) * CHAR_BIT >= 32) { // just to silence compiler warning + x |= (x >> 16u); + } if constexpr (sizeof(T) * CHAR_BIT >= 64) { // just to silence compiler warning x |= (x >> 32u); } @@ -67,11 +74,15 @@ constexpr inline T ctz(T x) noexcept { x &= -x; #endif if (x) c--; - if (sizeof(T) * CHAR_BIT >= 64) { + if constexpr (sizeof(T) * CHAR_BIT >= 64) { if (x & T(0x00000000FFFFFFFF)) c -= 32; } - if (x & T(0x0000FFFF0000FFFF)) c -= 16; - if (x & T(0x00FF00FF00FF00FF)) c -= 8; + if constexpr (sizeof(T) * CHAR_BIT >= 32) { + if (x & T(0x0000FFFF0000FFFF)) c -= 16; + } + if constexpr (sizeof(T) * CHAR_BIT >= 16) { + if (x & T(0x00FF00FF00FF00FF)) c -= 8; + } if (x & T(0x0F0F0F0F0F0F0F0F)) c -= 4; if (x & T(0x3333333333333333)) c -= 2; if (x & T(0x5555555555555555)) c -= 1; @@ -80,6 +91,24 @@ constexpr inline T ctz(T x) noexcept { } // namespace details +constexpr inline UTILS_PUBLIC UTILS_PURE +unsigned int UTILS_ALWAYS_INLINE clz(unsigned char x) noexcept { +#if __has_builtin(__builtin_clz) + return __builtin_clz((unsigned int)x) - 24; +#else + return details::clz(x); +#endif +} + +constexpr inline UTILS_PUBLIC UTILS_PURE +unsigned int UTILS_ALWAYS_INLINE clz(unsigned short x) noexcept { +#if __has_builtin(__builtin_clz) + return __builtin_clz((unsigned int)x) - 16; +#else + return details::clz(x); +#endif +} + constexpr inline UTILS_PUBLIC UTILS_PURE unsigned int UTILS_ALWAYS_INLINE clz(unsigned int x) noexcept { #if __has_builtin(__builtin_clz) @@ -107,6 +136,24 @@ unsigned long long UTILS_ALWAYS_INLINE clz(unsigned long long x) noexcept { #endif } +constexpr inline UTILS_PUBLIC UTILS_PURE +unsigned int UTILS_ALWAYS_INLINE ctz(unsigned char x) noexcept { +#if __has_builtin(__builtin_ctz) + return __builtin_ctz(x); +#else + return details::ctz(x); +#endif +} + +constexpr inline UTILS_PUBLIC UTILS_PURE +unsigned int UTILS_ALWAYS_INLINE ctz(unsigned short x) noexcept { +#if __has_builtin(__builtin_ctz) + return __builtin_ctz(x); +#else + return details::ctz(x); +#endif +} + constexpr inline UTILS_PUBLIC UTILS_PURE unsigned int UTILS_ALWAYS_INLINE ctz(unsigned int x) noexcept { #if __has_builtin(__builtin_ctz) @@ -134,6 +181,24 @@ unsigned long long UTILS_ALWAYS_INLINE ctz(unsigned long long x) noexcept { #endif } +constexpr inline UTILS_PUBLIC UTILS_PURE +unsigned int UTILS_ALWAYS_INLINE popcount(unsigned char x) noexcept { +#if __has_builtin(__builtin_popcount) + return __builtin_popcount(x); +#else + return details::popcount(x); +#endif +} + +constexpr inline UTILS_PUBLIC UTILS_PURE +unsigned int UTILS_ALWAYS_INLINE popcount(unsigned short x) noexcept { +#if __has_builtin(__builtin_popcount) + return __builtin_popcount(x); +#else + return details::popcount(x); +#endif +} + constexpr inline UTILS_PUBLIC UTILS_PURE unsigned int UTILS_ALWAYS_INLINE popcount(unsigned int x) noexcept { #if __has_builtin(__builtin_popcount) @@ -161,11 +226,6 @@ unsigned long long UTILS_ALWAYS_INLINE popcount(unsigned long long x) noexcept { #endif } -constexpr inline UTILS_PUBLIC UTILS_PURE -uint8_t UTILS_ALWAYS_INLINE popcount(uint8_t x) noexcept { - return (uint8_t)popcount((unsigned int)x); -} - template::value && std::is_unsigned::value>> constexpr inline UTILS_PUBLIC UTILS_PURE diff --git a/package/android/libs/filament/include/utils/bitset.h b/package/android/libs/filament/include/utils/bitset.h index 281e5dfc..8844fdb8 100644 --- a/package/android/libs/filament/include/utils/bitset.h +++ b/package/android/libs/filament/include/utils/bitset.h @@ -60,6 +60,11 @@ class UTILS_PUBLIC bitset { std::fill(std::begin(storage), std::end(storage), 0); } + template> + explicit bitset(U value) noexcept { + storage[0] = value; + } + T getBitsAt(size_t n) const noexcept { assert_invariant(n +#include + +#include + +namespace utils::io { + +class UTILS_PUBLIC sstream : public ostream { +public: + ostream& flush() noexcept override; + const char* c_str() const noexcept; + size_t length() const noexcept; +}; + +} // namespace utils::io + +#endif // TNT_UTILS_SSTREAM_H diff --git a/package/example/AppExamplePaper/ios/Podfile.lock b/package/example/AppExamplePaper/ios/Podfile.lock index 4d71c273..9542906c 100644 --- a/package/example/AppExamplePaper/ios/Podfile.lock +++ b/package/example/AppExamplePaper/ios/Podfile.lock @@ -935,7 +935,7 @@ PODS: - React-Mapbuffer (0.74.1): - glog - React-debug - - react-native-filament (1.2.0): + - react-native-filament (1.2.1): - DoubleConversion - glog - hermes-engine @@ -949,16 +949,16 @@ PODS: - React-featureflags - React-graphics - React-ImageManager - - react-native-filament/camutils (= 1.2.0) - - react-native-filament/filamat (= 1.2.0) - - react-native-filament/filament (= 1.2.0) - - react-native-filament/gltfio_core (= 1.2.0) - - react-native-filament/image (= 1.2.0) - - react-native-filament/ktxreader (= 1.2.0) - - react-native-filament/math (= 1.2.0) - - react-native-filament/tsl (= 1.2.0) - - react-native-filament/uberz (= 1.2.0) - - react-native-filament/utils (= 1.2.0) + - react-native-filament/camutils (= 1.2.1) + - react-native-filament/filamat (= 1.2.1) + - react-native-filament/filament (= 1.2.1) + - react-native-filament/gltfio_core (= 1.2.1) + - react-native-filament/image (= 1.2.1) + - react-native-filament/ktxreader (= 1.2.1) + - react-native-filament/math (= 1.2.1) + - react-native-filament/tsl (= 1.2.1) + - react-native-filament/uberz (= 1.2.1) + - react-native-filament/utils (= 1.2.1) - react-native-worklets-core - React-NativeModulesApple - React-RCTFabric @@ -967,7 +967,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-filament/camutils (1.2.0): + - react-native-filament/camutils (1.2.1): - DoubleConversion - glog - hermes-engine @@ -990,7 +990,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-filament/filamat (1.2.0): + - react-native-filament/filamat (1.2.1): - DoubleConversion - glog - hermes-engine @@ -1014,7 +1014,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-filament/filament (1.2.0): + - react-native-filament/filament (1.2.1): - DoubleConversion - glog - hermes-engine @@ -1038,7 +1038,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-filament/gltfio_core (1.2.0): + - react-native-filament/gltfio_core (1.2.1): - DoubleConversion - glog - hermes-engine @@ -1063,7 +1063,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-filament/image (1.2.0): + - react-native-filament/image (1.2.1): - DoubleConversion - glog - hermes-engine @@ -1086,7 +1086,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-filament/ktxreader (1.2.0): + - react-native-filament/ktxreader (1.2.1): - DoubleConversion - glog - hermes-engine @@ -1110,7 +1110,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-filament/math (1.2.0): + - react-native-filament/math (1.2.1): - DoubleConversion - glog - hermes-engine @@ -1132,7 +1132,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-filament/tsl (1.2.0): + - react-native-filament/tsl (1.2.1): - DoubleConversion - glog - hermes-engine @@ -1154,7 +1154,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-filament/uberz (1.2.0): + - react-native-filament/uberz (1.2.1): - DoubleConversion - glog - hermes-engine @@ -1179,7 +1179,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-filament/utils (1.2.0): + - react-native-filament/utils (1.2.1): - DoubleConversion - glog - hermes-engine @@ -1777,7 +1777,7 @@ SPEC CHECKSUMS: React-jsitracing: 233d1a798fe0ff33b8e630b8f00f62c4a8115fbc React-logger: 7e7403a2b14c97f847d90763af76b84b152b6fce React-Mapbuffer: 11029dcd47c5c9e057a4092ab9c2a8d10a496a33 - react-native-filament: eaf9684e5b82f40689320cb95bfadbaf48959c97 + react-native-filament: 610c24f51120ece3100387c6e277f53f177d7717 react-native-safe-area-context: dcab599c527c2d7de2d76507a523d20a0b83823d react-native-video: 9f29aee2feb9e42da24cb40b70d005d38a1a132f react-native-worklets-core: f51430dd07bf5343d4918d28a4bb00fe8f98b982 diff --git a/package/filament_ios_simulator.patch b/package/filament_ios_simulator.patch index f7eef22e..6d648759 100644 --- a/package/filament_ios_simulator.patch +++ b/package/filament_ios_simulator.patch @@ -1,8 +1,8 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt -index ed32949873a..35c10e6717e 100644 +index 283778b32..4d4ddfc4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -611,7 +611,11 @@ endif() +@@ -609,7 +609,11 @@ endif() string(TOLOWER "${DIST_ARCH}" DIST_ARCH) string(REPLACE "amd64" "x86_64" DIST_ARCH "${DIST_ARCH}") if (NOT DIST_DIR) @@ -16,7 +16,7 @@ index ed32949873a..35c10e6717e 100644 # ================================================================================================== diff --git a/NEW_RELEASE_NOTES.md b/NEW_RELEASE_NOTES.md -index 4a1a9c7fa7e..aa2ee9c76e0 100644 +index 4a1a9c7fa..aa2ee9c76 100644 --- a/NEW_RELEASE_NOTES.md +++ b/NEW_RELEASE_NOTES.md @@ -7,3 +7,4 @@ for next branch cut* header. @@ -25,10 +25,10 @@ index 4a1a9c7fa7e..aa2ee9c76e0 100644 ## Release notes for next branch cut +- ios: Add support for Apple Silicon (arm64) simulator diff --git a/build.sh b/build.sh -index 56562cc1c6c..3cb660aa1f9 100755 +index ab6440f45..c817f5a8d 100755 --- a/build.sh +++ b/build.sh -@@ -581,9 +581,9 @@ function build_ios_target { +@@ -593,9 +593,9 @@ function build_ios_target { local platform=$3 echo "Building iOS ${lc_target} (${arch}) for ${platform}..." @@ -40,9 +40,9 @@ index 56562cc1c6c..3cb660aa1f9 100755 if [[ ! -d "CMakeFiles" ]] || [[ "${ISSUE_CMAKE_ALWAYS}" == "true" ]]; then cmake \ -@@ -598,14 +598,14 @@ function build_ios_target { - ${MATDBG_OPTION} \ +@@ -611,14 +611,14 @@ function build_ios_target { ${MATOPT_OPTION} \ + ${STEREOSCOPIC_OPTION} \ ../.. - ln -sf "out/cmake-ios-${lc_target}-${arch}/compile_commands.json" \ + ln -sf "out/cmake-ios-${lc_target}-${arch}-${platform}/compile_commands.json" \ @@ -57,7 +57,7 @@ index 56562cc1c6c..3cb660aa1f9 100755 ${BUILD_COMMAND} ${INSTALL_COMMAND} fi -@@ -640,16 +640,26 @@ function build_ios { +@@ -653,16 +653,26 @@ function build_ios { if [[ "${ISSUE_DEBUG_BUILD}" == "true" ]]; then build_ios_target "Debug" "arm64" "iphoneos" if [[ "${IOS_BUILD_SIMULATOR}" == "true" ]]; then @@ -90,7 +90,7 @@ index 56562cc1c6c..3cb660aa1f9 100755 fi archive_ios "Debug" -@@ -657,19 +667,39 @@ function build_ios { +@@ -670,19 +680,39 @@ function build_ios { if [[ "${ISSUE_RELEASE_BUILD}" == "true" ]]; then build_ios_target "Release" "arm64" "iphoneos" @@ -141,7 +141,7 @@ index 56562cc1c6c..3cb660aa1f9 100755 } diff --git a/build/ios/create-xc-frameworks.sh b/build/ios/create-xc-frameworks.sh new file mode 100755 -index 00000000000..cf720cb7e4e +index 000000000..cf720cb7e --- /dev/null +++ b/build/ios/create-xc-frameworks.sh @@ -0,0 +1,107 @@ @@ -253,12 +253,12 @@ index 00000000000..cf720cb7e4e + eval $CMD +done diff --git a/ios/CocoaPods/Filament.podspec b/ios/CocoaPods/Filament.podspec -index 3ed06a44db5..3ffe1632473 100644 +index 45fce3980..b9674ca59 100644 --- a/ios/CocoaPods/Filament.podspec +++ b/ios/CocoaPods/Filament.podspec @@ -8,12 +8,6 @@ Pod::Spec.new do |spec| 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.53.0/filament-v1.53.0-ios.tgz" } - # Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon. - spec.pod_target_xcconfig = { @@ -402,7 +402,7 @@ index 3ed06a44db5..3ffe1632473 100644 ss.dependency "Filament/filamat" ss.dependency "Filament/tsl" diff --git a/ios/samples/README.md b/ios/samples/README.md -index 4c132849ee4..6c9c165eabb 100644 +index 4c132849e..6c9c165ea 100644 --- a/ios/samples/README.md +++ b/ios/samples/README.md @@ -47,7 +47,7 @@ build Filament in Release mode, replace `debug` with `release` in the above `bui @@ -415,7 +415,7 @@ index 4c132849ee4..6c9c165eabb 100644 ``` $ ./build.sh -s -p ios -i debug diff --git a/ios/samples/app-template.yml b/ios/samples/app-template.yml -index e8e14c50715..9c407448d16 100644 +index e8e14c507..9c407448d 100644 --- a/ios/samples/app-template.yml +++ b/ios/samples/app-template.yml @@ -17,25 +17,27 @@ targetTemplates: @@ -457,7 +457,7 @@ index e8e14c50715..9c407448d16 100644 GCC_PREPROCESSOR_DEFINITIONS: ["FILAMENT_APP_USE_METAL=1", "$(inherited)"] opengl: diff --git a/ios/samples/backend-test/backend-test.xcodeproj/project.pbxproj b/ios/samples/backend-test/backend-test.xcodeproj/project.pbxproj -index b47f4c00e36..ea4c11fe046 100644 +index b47f4c00e..ea4c11fe0 100644 --- a/ios/samples/backend-test/backend-test.xcodeproj/project.pbxproj +++ b/ios/samples/backend-test/backend-test.xcodeproj/project.pbxproj @@ -3,34 +3,112 @@ @@ -774,7 +774,7 @@ index b47f4c00e36..ea4c11fe046 100644 PRODUCT_BUNDLE_IDENTIFIER = "${SAMPLE_CODE_DISAMBIGUATOR}.google.filament.backend-test"; SAMPLE_CODE_DISAMBIGUATOR = "${DEVELOPMENT_TEAM}"; diff --git a/ios/samples/backend-test/backend-test.xcodeproj/xcshareddata/xcschemes/backend-test Metal.xcscheme b/ios/samples/backend-test/backend-test.xcodeproj/xcshareddata/xcschemes/backend-test Metal.xcscheme -index f4026437bcd..d6462758330 100644 +index f4026437b..d64627583 100644 --- a/ios/samples/backend-test/backend-test.xcodeproj/xcshareddata/xcschemes/backend-test Metal.xcscheme +++ b/ios/samples/backend-test/backend-test.xcodeproj/xcshareddata/xcschemes/backend-test Metal.xcscheme @@ -1,6 +1,6 @@ @@ -786,7 +786,7 @@ index f4026437bcd..d6462758330 100644 -+ T getParameter(const char* UTILS_NONNULL name, size_t nameLength) const; -+ -+ /** inline helper to provide the name as a null-terminated C string */ -+ template> -+ inline T getParameter(StringLiteral name) const { -+ return getParameter(name.data, name.size); -+ } -+ -+ /** inline helper to provide the name as a null-terminated C string */ -+ template> -+ inline T getParameter(const char* UTILS_NONNULL name) const { -+ return getParameter(name, strlen(name)); -+ } -+ - /** - * Set-up a custom scissor rectangle; by default it is disabled. - * -diff --git a/filament/src/MaterialInstance.cpp b/filament/src/MaterialInstance.cpp -index 33f3ab764..ee0af2de1 100644 ---- a/filament/src/MaterialInstance.cpp -+++ b/filament/src/MaterialInstance.cpp -@@ -75,6 +75,12 @@ inline void FMaterialInstance::setParameterImpl(std::string_view name, - setParameterUntypedImpl(name, value, count); - } - -+template -+T FMaterialInstance::getParameterImpl(std::string_view name) const noexcept { -+ ssize_t offset = mMaterial->getUniformInterfaceBlock().getFieldOffset(name, 0); -+ return downcast(this)->getUniformBuffer().getUniform(offset); -+} -+ - // ------------------------------------------------------------------------------------------------ - - template -@@ -183,6 +189,28 @@ template UTILS_PUBLIC void MaterialInstance::setParameter (const char* - - // ------------------------------------------------------------------------------------------------ - -+template -+T MaterialInstance::getParameter(const char* name, size_t nameLength) const { -+ return downcast(this)->getParameterImpl({ name, nameLength }); -+} -+ -+// explicit template instantiation of our supported types -+template UTILS_PUBLIC float MaterialInstance::getParameter (const char* name, size_t nameLength) const; -+template UTILS_PUBLIC int32_t MaterialInstance::getParameter (const char* name, size_t nameLength) const; -+template UTILS_PUBLIC uint32_t MaterialInstance::getParameter(const char* name, size_t nameLength) const; -+template UTILS_PUBLIC int2 MaterialInstance::getParameter (const char* name, size_t nameLength) const; -+template UTILS_PUBLIC int3 MaterialInstance::getParameter (const char* name, size_t nameLength) const; -+template UTILS_PUBLIC int4 MaterialInstance::getParameter (const char* name, size_t nameLength) const; -+template UTILS_PUBLIC uint2 MaterialInstance::getParameter (const char* name, size_t nameLength) const; -+template UTILS_PUBLIC uint3 MaterialInstance::getParameter (const char* name, size_t nameLength) const; -+template UTILS_PUBLIC uint4 MaterialInstance::getParameter (const char* name, size_t nameLength) const; -+template UTILS_PUBLIC float2 MaterialInstance::getParameter (const char* name, size_t nameLength) const; -+template UTILS_PUBLIC float3 MaterialInstance::getParameter (const char* name, size_t nameLength) const; -+template UTILS_PUBLIC float4 MaterialInstance::getParameter (const char* name, size_t nameLength) const; -+template UTILS_PUBLIC mat3f MaterialInstance::getParameter (const char* name, size_t nameLength) const; -+ -+// ------------------------------------------------------------------------------------------------ -+ - Material const* MaterialInstance::getMaterial() const noexcept { - return downcast(this)->getMaterial(); - } -diff --git a/filament/src/details/MaterialInstance.h b/filament/src/details/MaterialInstance.h -index 6be23b7e0..2f05bcf3f 100644 ---- a/filament/src/details/MaterialInstance.h -+++ b/filament/src/details/MaterialInstance.h -@@ -231,6 +231,9 @@ private: - void setParameterImpl(std::string_view name, - FTexture const* texture, TextureSampler const& sampler); - -+ template -+ T getParameterImpl(std::string_view name) const noexcept; -+ - FMaterialInstance() noexcept; - void initDefaultInstance(FEngine& engine, FMaterial const* material); - diff --git a/package/ios/libs/filament/include/backend/DriverEnums.h b/package/ios/libs/filament/include/backend/DriverEnums.h index ef1c655c..d69a9991 100644 --- a/package/ios/libs/filament/include/backend/DriverEnums.h +++ b/package/ios/libs/filament/include/backend/DriverEnums.h @@ -22,14 +22,17 @@ #include #include // Because we define ERROR in the FenceStatus enum. +#include #include +#include #include #include #include // FIXME: STL headers are not allowed in public headers #include // FIXME: STL headers are not allowed in public headers +#include // FIXME: STL headers are not allowed in public headers #include #include @@ -90,12 +93,15 @@ static constexpr uint64_t SWAP_CHAIN_HAS_STENCIL_BUFFER = SWAP_CHAIN_CON */ static constexpr uint64_t SWAP_CHAIN_CONFIG_PROTECTED_CONTENT = 0x40; - static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES. static constexpr size_t MAX_SAMPLER_COUNT = 62; // Maximum needed at feature level 3. static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects. static constexpr size_t MAX_SSBO_COUNT = 4; // This is guaranteed by OpenGL ES. +static constexpr size_t MAX_PUSH_CONSTANT_COUNT = 32; // Vulkan 1.1 spec allows for 128-byte + // of push constant (we assume 4-byte + // types). + // Per feature level caps // Use (int)FeatureLevel to index this array static constexpr struct { @@ -112,7 +118,7 @@ static_assert(MAX_VERTEX_BUFFER_COUNT <= MAX_VERTEX_ATTRIBUTE_COUNT, "The number of buffer objects that can be attached to a VertexBuffer must be " "less than or equal to the maximum number of vertex attributes."); -static constexpr size_t CONFIG_UNIFORM_BINDING_COUNT = 10; // This is guaranteed by OpenGL ES. +static constexpr size_t CONFIG_UNIFORM_BINDING_COUNT = 9; // This is guaranteed by OpenGL ES. static constexpr size_t CONFIG_SAMPLER_BINDING_COUNT = 4; // This is guaranteed by OpenGL ES. /** @@ -331,7 +337,7 @@ enum class UniformType : uint8_t { /** * Supported constant parameter types */ - enum class ConstantType : uint8_t { +enum class ConstantType : uint8_t { INT, FLOAT, BOOL @@ -686,7 +692,7 @@ enum class TextureUsage : uint16_t { SUBPASS_INPUT = 0x0020, //!< Texture can be used as a subpass input BLIT_SRC = 0x0040, //!< Texture can be used the source of a blit() BLIT_DST = 0x0080, //!< Texture can be used the destination of a blit() - PROTECTED = 0x0100, //!< Texture can be used the destination of a blit() + PROTECTED = 0x0100, //!< Texture can be used for protected content DEFAULT = UPLOADABLE | SAMPLEABLE //!< Default texture usage }; @@ -1218,13 +1224,15 @@ struct StencilState { uint8_t padding = 0; }; +using PushConstantVariant = std::variant; + static_assert(sizeof(StencilState::StencilOperations) == 5u, "StencilOperations size not what was intended"); static_assert(sizeof(StencilState) == 12u, "StencilState size not what was intended"); -using FrameScheduledCallback = void(*)(PresentCallable callable, void* user); +using FrameScheduledCallback = utils::Invocable; enum class Workaround : uint16_t { // The EASU pass must split because shader compiler flattens early-exit branch @@ -1243,13 +1251,7 @@ enum class Workaround : uint16_t { POWER_VR_SHADER_WORKAROUNDS, }; -//! The type of technique for stereoscopic rendering -enum class StereoscopicType : uint8_t { - // Stereoscopic rendering is performed using instanced rendering technique. - INSTANCED, - // Stereoscopic rendering is performed using the multiview feature from the graphics backend. - MULTIVIEW, -}; +using StereoscopicType = backend::Platform::StereoscopicType; } // namespace filament::backend diff --git a/package/ios/libs/filament/include/backend/Handle.h b/package/ios/libs/filament/include/backend/Handle.h index 4b63607a..c54e9609 100644 --- a/package/ios/libs/filament/include/backend/Handle.h +++ b/package/ios/libs/filament/include/backend/Handle.h @@ -75,6 +75,19 @@ class HandleBase { HandleBase(HandleBase const& rhs) noexcept = default; HandleBase& operator=(HandleBase const& rhs) noexcept = default; + HandleBase(HandleBase&& rhs) noexcept + : object(rhs.object) { + rhs.object = nullid; + } + + HandleBase& operator=(HandleBase&& rhs) noexcept { + if (this != &rhs) { + object = rhs.object; + rhs.object = nullid; + } + return *this; + } + private: HandleId object; }; @@ -89,8 +102,10 @@ struct Handle : public HandleBase { Handle() noexcept = default; Handle(Handle const& rhs) noexcept = default; + Handle(Handle&& rhs) noexcept = default; Handle& operator=(Handle const& rhs) noexcept = default; + Handle& operator=(Handle&& rhs) noexcept = default; explicit Handle(HandleId id) noexcept : HandleBase(id) { } diff --git a/package/ios/libs/filament/include/backend/Platform.h b/package/ios/libs/filament/include/backend/Platform.h index 03026dff..4f73c437 100644 --- a/package/ios/libs/filament/include/backend/Platform.h +++ b/package/ios/libs/filament/include/backend/Platform.h @@ -41,6 +41,26 @@ class UTILS_PUBLIC Platform { struct Fence {}; struct Stream {}; + /** + * The type of technique for stereoscopic rendering. (Note that the materials used will need to + * be compatible with the chosen technique.) + */ + enum class StereoscopicType : uint8_t { + /** + * No stereoscopic rendering + */ + NONE, + /** + * Stereoscopic rendering is performed using instanced rendering technique. + */ + INSTANCED, + /** + * Stereoscopic rendering is performed using the multiview feature from the graphics + * backend. + */ + MULTIVIEW, + }; + struct DriverConfig { /** * Size of handle arena in bytes. Setting to 0 indicates default value is to be used. @@ -65,6 +85,17 @@ class UTILS_PUBLIC Platform { * Disable backend handles use-after-free checks. */ bool disableHandleUseAfterFreeCheck = false; + + /** + * Force GLES2 context if supported, or pretend the context is ES2. Only meaningful on + * GLES 3.x backends. + */ + bool forceGLES2Context = false; + + /** + * Sets the technique for stereoscopic rendering. + */ + StereoscopicType stereoscopicType = StereoscopicType::NONE; }; Platform() noexcept; diff --git a/package/ios/libs/filament/include/backend/PresentCallable.h b/package/ios/libs/filament/include/backend/PresentCallable.h index 4402f222..f37d7704 100644 --- a/package/ios/libs/filament/include/backend/PresentCallable.h +++ b/package/ios/libs/filament/include/backend/PresentCallable.h @@ -48,7 +48,7 @@ namespace filament::backend { * and optional user data: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * swapChain->setFrameScheduledCallback(myFrameScheduledCallback, nullptr); + * swapChain->setFrameScheduledCallback(nullptr, myFrameScheduledCallback); * if (renderer->beginFrame(swapChain)) { * renderer->render(view); * renderer->endFrame(); @@ -58,8 +58,6 @@ namespace filament::backend { * @remark Only Filament's Metal backend supports PresentCallables and frame callbacks. Other * backends ignore the callback (which will never be called) and proceed normally. * - * @remark The SwapChain::FrameScheduledCallback is called on an arbitrary thread. - * * Applications *must* call each PresentCallable they receive. Each PresentCallable represents a * frame that is waiting to be presented. If an application fails to call a PresentCallable, a * memory leak could occur. To "cancel" the presentation of a frame, pass false to the diff --git a/package/ios/libs/filament/include/backend/Program.h b/package/ios/libs/filament/include/backend/Program.h index fe1c4a9b..7cec72cd 100644 --- a/package/ios/libs/filament/include/backend/Program.h +++ b/package/ios/libs/filament/include/backend/Program.h @@ -84,6 +84,9 @@ class Program { // null terminating character. Program& shader(ShaderStage shader, void const* data, size_t size); + // sets the language of the shader sources provided with shader() (defaults to ESSL3) + Program& shaderLanguage(ShaderLanguage shaderLanguage); + // Note: This is only needed for GLES3.0 backends, because the layout(binding=) syntax is // not permitted in glsl. The backend needs a way to associate a uniform block // to a binding point. @@ -114,6 +117,14 @@ class Program { Program& specializationConstants( utils::FixedCapacityVector specConstants) noexcept; + struct PushConstant { + utils::CString name; + ConstantType type; + }; + + Program& pushConstants(ShaderStage stage, + utils::FixedCapacityVector constants) noexcept; + Program& cacheId(uint64_t cacheId) noexcept; Program& multiview(bool multiview) noexcept; @@ -136,6 +147,8 @@ class Program { utils::CString const& getName() const noexcept { return mName; } utils::CString& getName() noexcept { return mName; } + auto const& getShaderLanguage() const { return mShaderLanguage; } + utils::FixedCapacityVector const& getSpecializationConstants() const noexcept { return mSpecializationConstants; } @@ -143,6 +156,15 @@ class Program { return mSpecializationConstants; } + utils::FixedCapacityVector const& getPushConstants( + ShaderStage stage) const noexcept { + return mPushConstants[static_cast(stage)]; + } + + utils::FixedCapacityVector& getPushConstants(ShaderStage stage) noexcept { + return mPushConstants[static_cast(stage)]; + } + uint64_t getCacheId() const noexcept { return mCacheId; } bool isMultiview() const noexcept { return mMultiview; } @@ -155,10 +177,12 @@ class Program { UniformBlockInfo mUniformBlocks = {}; SamplerGroupInfo mSamplerGroups = {}; ShaderSource mShadersSource; + ShaderLanguage mShaderLanguage = ShaderLanguage::ESSL3; utils::CString mName; uint64_t mCacheId{}; utils::Invocable mLogger; utils::FixedCapacityVector mSpecializationConstants; + std::array, SHADER_TYPE_COUNT> mPushConstants; utils::FixedCapacityVector> mAttributes; std::array mBindingUniformInfo; CompilerPriorityQueue mPriorityQueue = CompilerPriorityQueue::HIGH; diff --git a/package/ios/libs/filament/include/backend/TargetBufferInfo.h b/package/ios/libs/filament/include/backend/TargetBufferInfo.h index ce23fc5f..c4d284cc 100644 --- a/package/ios/libs/filament/include/backend/TargetBufferInfo.h +++ b/package/ios/libs/filament/include/backend/TargetBufferInfo.h @@ -29,17 +29,36 @@ namespace filament::backend { //! \privatesection struct TargetBufferInfo { + // note: the parameters of this constructor are not in the order of this structure's fields + TargetBufferInfo(Handle handle, uint8_t level, uint16_t layer, uint8_t baseViewIndex) noexcept + : handle(handle), baseViewIndex(baseViewIndex), level(level), layer(layer) { + } + + TargetBufferInfo(Handle handle, uint8_t level, uint16_t layer) noexcept + : handle(handle), level(level), layer(layer) { + } + + TargetBufferInfo(Handle handle, uint8_t level) noexcept + : handle(handle), level(level) { + } + + TargetBufferInfo(Handle handle) noexcept // NOLINT(*-explicit-constructor) + : handle(handle) { + } + + TargetBufferInfo() noexcept = default; + // texture to be used as render target Handle handle; - // starting layer index for multiview. This value is only used when the `layerCount` for the + // Starting layer index for multiview. This value is only used when the `layerCount` for the // render target is greater than 1. uint8_t baseViewIndex = 0; // level to be used uint8_t level = 0; - // for cubemaps and 3D textures. See TextureCubemapFace for the face->layer mapping + // For cubemaps and 3D textures. See TextureCubemapFace for the face->layer mapping uint16_t layer = 0; }; @@ -64,7 +83,7 @@ class MRT { MRT() noexcept = default; - MRT(TargetBufferInfo const& color) noexcept // NOLINT(hicpp-explicit-conversions) + MRT(TargetBufferInfo const& color) noexcept // NOLINT(hicpp-explicit-conversions, *-explicit-constructor) : mInfos{ color } { } @@ -84,7 +103,7 @@ class MRT { // this is here for backward compatibility MRT(Handle handle, uint8_t level, uint16_t layer) noexcept - : mInfos{{ handle, 0, level, layer }} { + : mInfos{{ handle, level, layer, 0 }} { } }; diff --git a/package/ios/libs/filament/include/backend/platforms/OpenGLPlatform.h b/package/ios/libs/filament/include/backend/platforms/OpenGLPlatform.h index dec6f47b..e00930c9 100644 --- a/package/ios/libs/filament/include/backend/platforms/OpenGLPlatform.h +++ b/package/ios/libs/filament/include/backend/platforms/OpenGLPlatform.h @@ -140,6 +140,23 @@ class OpenGLPlatform : public Platform { */ virtual uint32_t getDefaultFramebufferObject() noexcept; + /** + * Called by the backend when a frame starts. + * @param steady_clock_ns vsync time point on the monotonic clock + * @param refreshIntervalNs refresh interval in nanosecond + * @param frameId a frame id + */ + virtual void beginFrame( + int64_t monotonic_clock_ns, + int64_t refreshIntervalNs, + uint32_t frameId) noexcept; + + /** + * Called by the backend when a frame ends. + * @param frameId the frame id used in beginFrame + */ + virtual void endFrame( + uint32_t frameId) noexcept; /** * Type of contexts available @@ -191,6 +208,12 @@ class OpenGLPlatform : public Platform { utils::Invocable preContextChange, utils::Invocable postContextChange) noexcept; + /** + * Called by the backend just before calling commit() + * @see commit() + */ + virtual void preCommit() noexcept; + /** * Called by the driver once the current frame finishes drawing. Typically, this should present * the drawSwapChain. This is for example where `eglMakeCurrent()` would be called. diff --git a/package/ios/libs/filament/include/backend/platforms/PlatformEGLAndroid.h b/package/ios/libs/filament/include/backend/platforms/PlatformEGLAndroid.h index 32f83038..c3cc7da8 100644 --- a/package/ios/libs/filament/include/backend/platforms/PlatformEGLAndroid.h +++ b/package/ios/libs/filament/include/backend/platforms/PlatformEGLAndroid.h @@ -22,6 +22,10 @@ #include #include +#include + +#include + #include #include @@ -58,6 +62,13 @@ class PlatformEGLAndroid : public PlatformEGL { void terminate() noexcept override; + void beginFrame( + int64_t monotonic_clock_ns, + int64_t refreshIntervalNs, + uint32_t frameId) noexcept override; + + void preCommit() noexcept override; + /** * Set the presentation time using `eglPresentationTimeANDROID` * @param presentationTimeInNanosecond @@ -79,8 +90,18 @@ class PlatformEGLAndroid : public PlatformEGL { AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept override; private: + struct InitializeJvmForPerformanceManagerIfNeeded { + InitializeJvmForPerformanceManagerIfNeeded(); + }; + int mOSVersion; ExternalStreamManagerAndroid& mExternalStreamManager; + InitializeJvmForPerformanceManagerIfNeeded const mInitializeJvmForPerformanceManagerIfNeeded; + utils::PerformanceHintManager mPerformanceHintManager; + utils::PerformanceHintManager::Session mPerformanceHintSession; + + using clock = std::chrono::high_resolution_clock; + clock::time_point mStartTimeOfActualWork; }; } // namespace filament::backend diff --git a/package/ios/libs/filament/include/backend/platforms/VulkanPlatform.h b/package/ios/libs/filament/include/backend/platforms/VulkanPlatform.h index 6201d644..2bbe1983 100644 --- a/package/ios/libs/filament/include/backend/platforms/VulkanPlatform.h +++ b/package/ios/libs/filament/include/backend/platforms/VulkanPlatform.h @@ -23,9 +23,9 @@ #include #include +#include #include -#include #include #include @@ -47,6 +47,14 @@ struct VulkanPlatformPrivate; class VulkanPlatform : public Platform, utils::PrivateImplementation { public: + struct ExtensionHashFn { + std::size_t operator()(utils::CString const& s) const noexcept { + return std::hash{}(s.data()); + } + }; + // Utility for managing device or instance extensions during initialization. + using ExtensionSet = std::unordered_set; + /** * A collection of handles to objects and metadata that comprises a Vulkan context. The client * can instantiate this struct and pass to Engine::Builder::sharedContext if they wishes to @@ -82,6 +90,20 @@ class VulkanPlatform : public Platform, utils::PrivateImplementation explicitImageReadyWait = nullptr; + }; + VulkanPlatform(); ~VulkanPlatform() override; @@ -119,6 +141,12 @@ class VulkanPlatform : public Platform, utils::PrivateImplementation; - static ExtensionSet getRequiredInstanceExtensions(); + static ExtensionSet getSwapchainInstanceExtensions(); + // Platform dependent helper methods using SurfaceBundle = std::tuple; static SurfaceBundle createVkSurfaceKHR(void* nativeWindow, VkInstance instance, uint64_t flags) noexcept; diff --git a/package/ios/libs/filament/include/filamat/MaterialBuilder.h b/package/ios/libs/filament/include/filamat/MaterialBuilder.h index 4b66965d..c3045b94 100644 --- a/package/ios/libs/filament/include/filamat/MaterialBuilder.h +++ b/package/ios/libs/filament/include/filamat/MaterialBuilder.h @@ -245,6 +245,7 @@ class UTILS_PUBLIC MaterialBuilder : public MaterialBuilderBase { using CullingMode = filament::backend::CullingMode; using FeatureLevel = filament::backend::FeatureLevel; using StereoscopicType = filament::backend::StereoscopicType; + using ShaderStage = filament::backend::ShaderStage; enum class VariableQualifier : uint8_t { OUT @@ -692,6 +693,12 @@ class UTILS_PUBLIC MaterialBuilder : public MaterialBuilderBase { } defaultValue; }; + struct PushConstant { + utils::CString name; + ConstantType type; + ShaderStage stage; + }; + static constexpr size_t MATERIAL_PROPERTIES_COUNT = filament::MATERIAL_PROPERTIES_COUNT; using Property = filament::Property; @@ -720,6 +727,7 @@ class UTILS_PUBLIC MaterialBuilder : public MaterialBuilderBase { using SubpassList = Parameter[MAX_SUBPASS_COUNT]; using BufferList = std::vector>; using ConstantList = std::vector; + using PushConstantList = std::vector; // returns the number of parameters declared in this material uint8_t getParameterCount() const noexcept { return mParameterCount; } @@ -763,6 +771,10 @@ class UTILS_PUBLIC MaterialBuilder : public MaterialBuilderBase { void prepareToBuild(MaterialInfo& info) noexcept; + // Initialize internal push constants that will both be written to the shaders and material + // chunks (like user-defined spec constants). + void initPushConstants() noexcept; + // Return true if the shader is syntactically and semantically valid. // This method finds all the properties defined in the fragment and // vertex shaders of the material. @@ -829,6 +841,7 @@ class UTILS_PUBLIC MaterialBuilder : public MaterialBuilderBase { PropertyList mProperties; ParameterList mParameters; ConstantList mConstants; + PushConstantList mPushConstants; SubpassList mSubpasses; VariableList mVariables; OutputList mOutputs; diff --git a/package/ios/libs/filament/include/filament/Engine.h b/package/ios/libs/filament/include/filament/Engine.h index b741d3ab..2aed8273 100644 --- a/package/ios/libs/filament/include/filament/Engine.h +++ b/package/ios/libs/filament/include/filament/Engine.h @@ -315,7 +315,7 @@ class UTILS_PUBLIC Engine { * * @see View::setStereoscopicOptions */ - StereoscopicType stereoscopicType = StereoscopicType::INSTANCED; + StereoscopicType stereoscopicType = StereoscopicType::NONE; /* * The number of eyes to render when stereoscopic rendering is enabled. Supported values are @@ -340,6 +340,35 @@ class UTILS_PUBLIC Engine { * Disable backend handles use-after-free checks. */ bool disableHandleUseAfterFreeCheck = false; + + /* + * Sets a preferred shader language for Filament to use. + * + * The Metal backend supports two shader languages: MSL (Metal Shading Language) and + * METAL_LIBRARY (precompiled .metallib). This option controls which shader language is + * used when materials contain both. + * + * By default, when preferredShaderLanguage is unset, Filament will prefer METAL_LIBRARY + * shaders if present within a material, falling back to MSL. Setting + * preferredShaderLanguage to ShaderLanguage::MSL will instead instruct Filament to check + * for the presence of MSL in a material first, falling back to METAL_LIBRARY if MSL is not + * present. + * + * When using a non-Metal backend, setting this has no effect. + */ + enum class ShaderLanguage { + DEFAULT = 0, + MSL = 1, + METAL_LIBRARY = 2, + }; + ShaderLanguage preferredShaderLanguage = ShaderLanguage::DEFAULT; + + /* + * When the OpenGL ES backend is used, setting this value to true will force a GLES2.0 + * context if supported by the Platform, or if not, will have the backend pretend + * it's a GLES2 context. Ignored on other backends. + */ + bool forceGLES2Context = false; }; @@ -800,24 +829,51 @@ class UTILS_PUBLIC Engine { bool destroy(const InstanceBuffer* UTILS_NULLABLE p); //!< Destroys an InstanceBuffer object. void destroy(utils::Entity e); //!< Destroys all filament-known components from this entity - bool isValid(const BufferObject* UTILS_NULLABLE p); //!< Tells whether a BufferObject object is valid - bool isValid(const VertexBuffer* UTILS_NULLABLE p); //!< Tells whether an VertexBuffer object is valid - bool isValid(const Fence* UTILS_NULLABLE p); //!< Tells whether a Fence object is valid - bool isValid(const IndexBuffer* UTILS_NULLABLE p); //!< Tells whether an IndexBuffer object is valid - bool isValid(const SkinningBuffer* UTILS_NULLABLE p); //!< Tells whether a SkinningBuffer object is valid - bool isValid(const MorphTargetBuffer* UTILS_NULLABLE p); //!< Tells whether a MorphTargetBuffer object is valid - bool isValid(const IndirectLight* UTILS_NULLABLE p); //!< Tells whether an IndirectLight object is valid - bool isValid(const Material* UTILS_NULLABLE p); //!< Tells whether an IndirectLight object is valid - bool isValid(const Renderer* UTILS_NULLABLE p); //!< Tells whether a Renderer object is valid - bool isValid(const Scene* UTILS_NULLABLE p); //!< Tells whether a Scene object is valid - bool isValid(const Skybox* UTILS_NULLABLE p); //!< Tells whether a SkyBox object is valid - bool isValid(const ColorGrading* UTILS_NULLABLE p); //!< Tells whether a ColorGrading object is valid - bool isValid(const SwapChain* UTILS_NULLABLE p); //!< Tells whether a SwapChain object is valid - bool isValid(const Stream* UTILS_NULLABLE p); //!< Tells whether a Stream object is valid - bool isValid(const Texture* UTILS_NULLABLE p); //!< Tells whether a Texture object is valid - bool isValid(const RenderTarget* UTILS_NULLABLE p); //!< Tells whether a RenderTarget object is valid - bool isValid(const View* UTILS_NULLABLE p); //!< Tells whether a View object is valid - bool isValid(const InstanceBuffer* UTILS_NULLABLE p); //!< Tells whether an InstanceBuffer object is valid + /** Tells whether a BufferObject object is valid */ + bool isValid(const BufferObject* UTILS_NULLABLE p) const; + /** Tells whether an VertexBuffer object is valid */ + bool isValid(const VertexBuffer* UTILS_NULLABLE p) const; + /** Tells whether a Fence object is valid */ + bool isValid(const Fence* UTILS_NULLABLE p) const; + /** Tells whether an IndexBuffer object is valid */ + bool isValid(const IndexBuffer* UTILS_NULLABLE p) const; + /** Tells whether a SkinningBuffer object is valid */ + bool isValid(const SkinningBuffer* UTILS_NULLABLE p) const; + /** Tells whether a MorphTargetBuffer object is valid */ + bool isValid(const MorphTargetBuffer* UTILS_NULLABLE p) const; + /** Tells whether an IndirectLight object is valid */ + bool isValid(const IndirectLight* UTILS_NULLABLE p) const; + /** Tells whether an Material object is valid */ + bool isValid(const Material* UTILS_NULLABLE p) const; + /** Tells whether an MaterialInstance object is valid. Use this if you already know + * which Material this MaterialInstance belongs to. DO NOT USE getMaterial(), this would + * defeat the purpose of validating the MaterialInstance. + */ + bool isValid(const Material* UTILS_NONNULL m, const MaterialInstance* UTILS_NULLABLE p) const; + /** Tells whether an MaterialInstance object is valid. Use this if the Material the + * MaterialInstance belongs to is not known. This method can be expensive. + */ + bool isValidExpensive(const MaterialInstance* UTILS_NULLABLE p) const; + /** Tells whether a Renderer object is valid */ + bool isValid(const Renderer* UTILS_NULLABLE p) const; + /** Tells whether a Scene object is valid */ + bool isValid(const Scene* UTILS_NULLABLE p) const; + /** Tells whether a SkyBox object is valid */ + bool isValid(const Skybox* UTILS_NULLABLE p) const; + /** Tells whether a ColorGrading object is valid */ + bool isValid(const ColorGrading* UTILS_NULLABLE p) const; + /** Tells whether a SwapChain object is valid */ + bool isValid(const SwapChain* UTILS_NULLABLE p) const; + /** Tells whether a Stream object is valid */ + bool isValid(const Stream* UTILS_NULLABLE p) const; + /** Tells whether a Texture object is valid */ + bool isValid(const Texture* UTILS_NULLABLE p) const; + /** Tells whether a RenderTarget object is valid */ + bool isValid(const RenderTarget* UTILS_NULLABLE p) const; + /** Tells whether a View object is valid */ + bool isValid(const View* UTILS_NULLABLE p) const; + /** Tells whether an InstanceBuffer object is valid */ + bool isValid(const InstanceBuffer* UTILS_NULLABLE p) const; /** * Kicks the hardware thread (e.g. the OpenGL, Vulkan or Metal thread) and blocks until @@ -840,6 +896,15 @@ class UTILS_PUBLIC Engine { */ void flush(); + /** + * Get paused state of rendering thread. + * + *

Warning: This is an experimental API. + * + * @see setPaused + */ + bool isPaused() const noexcept; + /** * Pause or resume rendering thread. * @@ -865,6 +930,14 @@ class UTILS_PUBLIC Engine { */ void pumpMessageQueues(); + /** + * Switch the command queue to unprotected mode. Protected mode can be activated via + * Renderer::beginFrame() using a protected SwapChain. + * @see Renderer + * @see SwapChain + */ + void unprotected() noexcept; + /** * Returns the default Material. * diff --git a/package/ios/libs/filament/include/filament/MaterialChunkType.h b/package/ios/libs/filament/include/filament/MaterialChunkType.h index c80ac7d8..4a4561c1 100644 --- a/package/ios/libs/filament/include/filament/MaterialChunkType.h +++ b/package/ios/libs/filament/include/filament/MaterialChunkType.h @@ -53,6 +53,7 @@ enum UTILS_PUBLIC ChunkType : uint64_t { MaterialAttributeInfo = charTo64bitNum("MAT_ATTR"), MaterialProperties = charTo64bitNum("MAT_PROP"), MaterialConstants = charTo64bitNum("MAT_CONS"), + MaterialPushConstants = charTo64bitNum("MAT_PCON"), MaterialName = charTo64bitNum("MAT_NAME"), MaterialVersion = charTo64bitNum("MAT_VERS"), diff --git a/package/ios/libs/filament/include/filament/MaterialEnums.h b/package/ios/libs/filament/include/filament/MaterialEnums.h index 9f348481..c15c6c45 100644 --- a/package/ios/libs/filament/include/filament/MaterialEnums.h +++ b/package/ios/libs/filament/include/filament/MaterialEnums.h @@ -28,7 +28,7 @@ namespace filament { // update this when a new version of filament wouldn't work with older materials -static constexpr size_t MATERIAL_VERSION = 51; +static constexpr size_t MATERIAL_VERSION = 53; /** * Supported shading models diff --git a/package/ios/libs/filament/include/filament/MaterialInstance.h b/package/ios/libs/filament/include/filament/MaterialInstance.h index 7252f9a4..2b8aaa9a 100644 --- a/package/ios/libs/filament/include/filament/MaterialInstance.h +++ b/package/ios/libs/filament/include/filament/MaterialInstance.h @@ -140,6 +140,7 @@ class UTILS_PUBLIC MaterialInstance : public FilamentAPI { * @param values Array of values to set to the named parameter array. * @param count Size of the array to set. * @throws utils::PreConditionPanic if name doesn't exist or no-op if exceptions are disabled. + * @see Material::hasParameter */ template> void setParameter(const char* UTILS_NONNULL name, size_t nameLength, @@ -237,9 +238,13 @@ class UTILS_PUBLIC MaterialInstance : public FilamentAPI { /** * Gets the value of a parameter by name. * + * Note: Only supports non-texture parameters such as numeric and math types. + * * @param name Name of the parameter as defined by Material. Cannot be nullptr. * @param nameLength Length in `char` of the name parameter. * @throws utils::PreConditionPanic if name doesn't exist or no-op if exceptions are disabled. + * + * @see Material::hasParameter */ template T getParameter(const char* UTILS_NONNULL name, size_t nameLength) const; diff --git a/package/ios/libs/filament/include/filament/RenderableManager.h b/package/ios/libs/filament/include/filament/RenderableManager.h index bb50b7d1..363ef2d7 100644 --- a/package/ios/libs/filament/include/filament/RenderableManager.h +++ b/package/ios/libs/filament/include/filament/RenderableManager.h @@ -464,15 +464,30 @@ class UTILS_PUBLIC RenderableManager : public FilamentAPI { Builder& boneIndicesAndWeights(size_t primitiveIndex, utils::FixedCapacityVector< utils::FixedCapacityVector> indicesAndWeightsVector) noexcept; + + /** + * Controls if the renderable has legacy vertex morphing targets, zero by default. This is + * required to enable GPU morphing. + * + * For legacy morphing, the attached VertexBuffer must provide data in the + * appropriate VertexAttribute slots (\c MORPH_POSITION_0 etc). Legacy morphing only + * supports up to 4 morph targets and will be deprecated in the future. Legacy morphing must + * be enabled on the material definition: either via the legacyMorphing material attribute + * or by calling filamat::MaterialBuilder::useLegacyMorphing(). + * + * See also RenderableManager::setMorphWeights(), which can be called on a per-frame basis + * to advance the animation. + */ + Builder& morphing(size_t targetCount) noexcept; + /** * Controls if the renderable has vertex morphing targets, zero by default. This is * required to enable GPU morphing. * * Filament supports two morphing modes: standard (default) and legacy. * - * For standard morphing, A MorphTargetBuffer must be created and provided via - * RenderableManager::setMorphTargetBufferAt(). Standard morphing supports up to - * \c CONFIG_MAX_MORPH_TARGET_COUNT morph targets. + * For standard morphing, A MorphTargetBuffer must be provided. + * Standard morphing supports up to \c CONFIG_MAX_MORPH_TARGET_COUNT morph targets. * * For legacy morphing, the attached VertexBuffer must provide data in the * appropriate VertexAttribute slots (\c MORPH_POSITION_0 etc). Legacy morphing only @@ -483,29 +498,35 @@ class UTILS_PUBLIC RenderableManager : public FilamentAPI { * See also RenderableManager::setMorphWeights(), which can be called on a per-frame basis * to advance the animation. */ - Builder& morphing(size_t targetCount) noexcept; + Builder& morphing(MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer) noexcept; /** - * Specifies the morph target buffer for a primitive. - * - * The morph target buffer must have an associated renderable and geometry. Two conditions - * must be met: - * 1. The number of morph targets in the buffer must equal the renderable's morph target - * count. - * 2. The vertex count of each morph target must equal the geometry's vertex count. + * @deprecated Use morphing(uint8_t level, size_t primitiveIndex, size_t offset, size_t count) instead + */ + Builder& morphing(uint8_t level, size_t primitiveIndex, + MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer, + size_t offset, size_t count) noexcept; + + /** + * @deprecated Use morphing(uint8_t level, size_t primitiveIndex, size_t offset, size_t count) instead + */ + inline Builder& morphing(uint8_t level, size_t primitiveIndex, + MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer) noexcept { + return morphing(level, primitiveIndex, morphTargetBuffer, 0, + morphTargetBuffer->getVertexCount()); + } + + /** + * Specifies the the range of the MorphTargetBuffer to use with this primitive. * * @param level the level of detail (lod), only 0 can be specified * @param primitiveIndex zero-based index of the primitive, must be less than the count passed to Builder constructor - * @param morphTargetBuffer specifies the morph target buffer * @param offset specifies where in the morph target buffer to start reading (expressed as a number of vertices) * @param count number of vertices in the morph target buffer to read, must equal the geometry's count (for triangles, this should be a multiple of 3) */ Builder& morphing(uint8_t level, size_t primitiveIndex, - MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer, size_t offset, size_t count) noexcept; - inline Builder& morphing(uint8_t level, size_t primitiveIndex, - MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer) noexcept; /** * Sets the drawing order for blended primitives. The drawing order is either global or @@ -765,14 +786,19 @@ class UTILS_PUBLIC RenderableManager : public FilamentAPI { /** * Associates a MorphTargetBuffer to the given primitive. */ + void setMorphTargetBufferAt(Instance instance, uint8_t level, size_t primitiveIndex, + size_t offset, size_t count); + + /** @deprecated */ void setMorphTargetBufferAt(Instance instance, uint8_t level, size_t primitiveIndex, MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer, size_t offset, size_t count); - /** - * Utility method to change a MorphTargetBuffer to the given primitive - */ + /** @deprecated */ inline void setMorphTargetBufferAt(Instance instance, uint8_t level, size_t primitiveIndex, - MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer); + MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer) { + setMorphTargetBufferAt(instance, level, primitiveIndex, morphTargetBuffer, 0, + morphTargetBuffer->getVertexCount()); + } /** * Get a MorphTargetBuffer to the given primitive or null if it doesn't exist. @@ -906,20 +932,6 @@ class UTILS_PUBLIC RenderableManager : public FilamentAPI { ~RenderableManager() = default; }; -RenderableManager::Builder& RenderableManager::Builder::morphing( - uint8_t level, size_t primitiveIndex, - MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer) noexcept { - return morphing(level, primitiveIndex, morphTargetBuffer, 0, - morphTargetBuffer->getVertexCount()); -} - -void RenderableManager::setMorphTargetBufferAt( - Instance instance, uint8_t level, size_t primitiveIndex, - MorphTargetBuffer* UTILS_NONNULL morphTargetBuffer) { - setMorphTargetBufferAt(instance, level, primitiveIndex, morphTargetBuffer, 0, - morphTargetBuffer->getVertexCount()); -} - template Box RenderableManager::computeAABB( VECTOR const* UTILS_NONNULL vertices, diff --git a/package/ios/libs/filament/include/filament/SwapChain.h b/package/ios/libs/filament/include/filament/SwapChain.h index 0af01afc..6917507a 100644 --- a/package/ios/libs/filament/include/filament/SwapChain.h +++ b/package/ios/libs/filament/include/filament/SwapChain.h @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -115,7 +116,7 @@ class Engine; * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * SDL_SysWMinfo wmi; * SDL_VERSION(&wmi.version); - * ASSERT_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi), "SDL version unsupported!"); + * FILAMENT_CHECK_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi)) << "SDL version unsupported!"; * HDC nativeWindow = (HDC) wmi.info.win.hdc; * * using namespace filament; @@ -264,13 +265,22 @@ class UTILS_PUBLIC SwapChain : public FilamentAPI { * backend. * * A FrameScheduledCallback can be set on an individual SwapChain through - * SwapChain::setFrameScheduledCallback. If the callback is set, then the SwapChain will *not* - * automatically schedule itself for presentation. Instead, the application must call the - * PresentCallable passed to the FrameScheduledCallback. + * SwapChain::setFrameScheduledCallback. If the callback is set for a given frame, then the + * SwapChain will *not* automatically schedule itself for presentation. Instead, the application + * must call the PresentCallable passed to the FrameScheduledCallback. * - * There may be only one FrameScheduledCallback set per SwapChain. A call to - * SwapChain::setFrameScheduledCallback will overwrite any previous FrameScheduledCallbacks set - * on the same SwapChain. + * Each SwapChain can have only one FrameScheduledCallback set per frame. If + * setFrameScheduledCallback is called multiple times on the same SwapChain before + * Renderer::endFrame(), the most recent call effectively overwrites any previously set + * callback. This allows the callback to be updated as needed before the frame has finished + * encoding. + * + * The "last" callback set by setFrameScheduledCallback gets "latched" when Renderer::endFrame() + * is executed. At this point, the state of the callback is fixed and is the one used for the + * frame that was just encoded. Subsequent changes to the callback using + * setFrameScheduledCallback after endFrame() apply to the next frame. + * + * Use \c setFrameScheduledCallback() (with default arguments) to unset the callback. * * If your application delays the call to the PresentCallable by, for example, calling it on a * separate thread, you must ensure all PresentCallables have been called before shutting down @@ -278,28 +288,26 @@ class UTILS_PUBLIC SwapChain : public FilamentAPI { * Engine::shutdown. This is necessary to ensure the Filament Engine has had a chance to clean * up all memory related to frame presentation. * - * @param callback A callback, or nullptr to unset. - * @param user An optional pointer to user data passed to the callback function. + * @param handler Handler to dispatch the callback or nullptr for the default handler. + * @param callback Callback called when the frame is scheduled. * * @remark Only Filament's Metal backend supports PresentCallables and frame callbacks. Other * backends ignore the callback (which will never be called) and proceed normally. * - * @remark The SwapChain::FrameScheduledCallback is called on an arbitrary thread. - * + * @see CallbackHandler * @see PresentCallable */ - void setFrameScheduledCallback(FrameScheduledCallback UTILS_NULLABLE callback, - void* UTILS_NULLABLE user = nullptr); + void setFrameScheduledCallback(backend::CallbackHandler* UTILS_NULLABLE handler = nullptr, + FrameScheduledCallback&& callback = {}); /** - * Returns the SwapChain::FrameScheduledCallback that was previously set with - * SwapChain::setFrameScheduledCallback, or nullptr if one is not set. + * Returns whether or not this SwapChain currently has a FrameScheduledCallback set. * - * @return the previously-set FrameScheduledCallback, or nullptr + * @return true, if the last call to setFrameScheduledCallback set a callback * * @see SwapChain::setFrameCompletedCallback */ - UTILS_NULLABLE FrameScheduledCallback getFrameScheduledCallback() const noexcept; + bool isFrameScheduledCallbackSet() const noexcept; /** * FrameCompletedCallback is a callback function that notifies an application when a frame's diff --git a/package/ios/libs/filament/include/filament/View.h b/package/ios/libs/filament/include/filament/View.h index 3cdd527f..1a1ed96f 100644 --- a/package/ios/libs/filament/include/filament/View.h +++ b/package/ios/libs/filament/include/filament/View.h @@ -189,6 +189,13 @@ class UTILS_PUBLIC View : public FilamentAPI { */ void setCamera(Camera* UTILS_NONNULL camera) noexcept; + /** + * Returns whether a Camera is set. + * @return true if a camera is set. + * @see setCamera() + */ + bool hasCamera() const noexcept; + /** * Returns the Camera currently associated with this View. * @return A reference to the Camera associated to this View. diff --git a/package/ios/libs/filament/include/gltfio/AssetLoader.h b/package/ios/libs/filament/include/gltfio/AssetLoader.h index f516166a..bf650f69 100644 --- a/package/ios/libs/filament/include/gltfio/AssetLoader.h +++ b/package/ios/libs/filament/include/gltfio/AssetLoader.h @@ -38,6 +38,23 @@ namespace filament::gltfio { class NodeManager; +// Use this struct to enable mikktspace-based tangent-space computation. +/** + * \struct AssetConfigurationExtended AssetLoader.h gltfio/AssetLoader.h + * \brief extends struct AssetConfiguration + * Useful if client needs mikktspace tangent space computation. + * NOTE: Android, iOS, Web are not supported. And only disk-local glTF resources are supported. + */ +struct AssetConfigurationExtended { + //! Optional The same parameter as provided to \struct ResourceConfiguration ResourceLoader.h + //! gltfio/ResourceLoader.h + char const* gltfPath; + + //! Client can use this method to check if the extended implementation is supported on their + //! platform or not. + static bool isSupported(); +}; + /** * \struct AssetConfiguration AssetLoader.h gltfio/AssetLoader.h * \brief Construction parameters for AssetLoader. @@ -62,6 +79,10 @@ struct AssetConfiguration { //! Optional default node name for anonymous nodes char* defaultNodeName = nullptr; + + //! Optional to enable mikktspace tangents. Lifetime of struct only needs to be maintained for + // the duration of the constructor of AssetLoader. + AssetConfigurationExtended* ext = nullptr; }; /** diff --git a/package/ios/libs/filament/include/utils/FixedCapacityVector.h b/package/ios/libs/filament/include/utils/FixedCapacityVector.h index f3990124..1221e7cc 100644 --- a/package/ios/libs/filament/include/utils/FixedCapacityVector.h +++ b/package/ios/libs/filament/include/utils/FixedCapacityVector.h @@ -299,6 +299,16 @@ class UTILS_PUBLIC FixedCapacityVector { } } + UTILS_NOINLINE + void shrink_to_fit() { + if (size() < capacity()) { + FixedCapacityVector t(construct_with_capacity, size(), allocator()); + t.mSize = size(); + std::uninitialized_move(begin(), end(), t.begin()); + this->swap(t); + } + } + private: enum construct_with_capacity_tag{ construct_with_capacity }; @@ -318,9 +328,9 @@ class UTILS_PUBLIC FixedCapacityVector { iterator assertCapacityForSize(size_type s) { if constexpr(CapacityCheck || FILAMENT_FORCE_CAPACITY_CHECK) { - ASSERT_PRECONDITION(capacity() >= s, - "capacity exceeded: requested size %lu, available capacity %lu.", - (unsigned long)s, (unsigned long)capacity()); + FILAMENT_CHECK_PRECONDITION(capacity() >= s) + << "capacity exceeded: requested size " << (unsigned long)s + << "u, available capacity " << (unsigned long)capacity() << "u."; } return end(); } diff --git a/package/ios/libs/filament/include/utils/Panic.h b/package/ios/libs/filament/include/utils/Panic.h index c658da4b..6e9ac3f4 100644 --- a/package/ios/libs/filament/include/utils/Panic.h +++ b/package/ios/libs/filament/include/utils/Panic.h @@ -17,14 +17,28 @@ #ifndef TNT_UTILS_PANIC_H #define TNT_UTILS_PANIC_H +#ifdef FILAMENT_PANIC_USES_ABSL +# if FILAMENT_PANIC_USES_ABSL +# include "absl/log/log.h" +# define FILAMENT_CHECK_PRECONDITION CHECK +# define FILAMENT_CHECK_POSTCONDITION CHECK +# define FILAMENT_CHECK_ARITHMETIC CHECK +# endif +#endif + #include #include +#include #include +#include #ifdef __EXCEPTIONS # define UTILS_EXCEPTIONS 1 #else +# ifdef UTILS_EXCEPTIONS +# error UTILS_EXCEPTIONS is already defined! +# endif #endif /** @@ -280,12 +294,24 @@ class UTILS_PUBLIC Panic { */ virtual const char* what() const noexcept = 0; + /** + * Get the type of the panic (e.g. "Precondition") + * @return a C string containing the type of panic + */ + virtual const char* getType() const noexcept = 0; + /** * Get the reason string for the panic * @return a C string containing the reason for the panic */ virtual const char* getReason() const noexcept = 0; + /** + * Get a version of the reason string that is guaranteed to be constructed from literal + * strings only; it will contain no runtime information. + */ + virtual const char* getReasonLiteral() 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. @@ -334,7 +360,9 @@ class UTILS_PUBLIC TPanic : public Panic { const char* what() const noexcept override; // Panic interface + const char* getType() const noexcept override; const char* getReason() const noexcept override; + const char* getReasonLiteral() const noexcept override; const char* getFunction() const noexcept override; const char* getFile() const noexcept override; int getLine() const noexcept override; @@ -348,13 +376,14 @@ class UTILS_PUBLIC TPanic : public Panic { * @param function the name of the function where the error was detected * @param file the file where the above function in implemented * @param line the line in the above file where the error was detected + * @param literal a literal version of the error message * @param format printf style string describing the error * @see ASSERT_PRECONDITION, ASSERT_POSTCONDITION, ASSERT_ARITHMETIC * @see PANIC_PRECONDITION, PANIC_POSTCONDITION, PANIC_ARITHMETIC * @see setMode() */ - static void panic(char const* function, char const* file, int line, const char* format, ...) - UTILS_NORETURN; + static void panic(char const* function, char const* file, int line, char const* literal, + const char* format, ...) UTILS_NORETURN; /** * Depending on the mode set, either throws an exception of type T with the given reason plus @@ -363,43 +392,41 @@ class UTILS_PUBLIC TPanic : public Panic { * @param function the name of the function where the error was detected * @param file the file where the above function in implemented * @param line the line in the above file where the error was detected - * @param s std::string describing the error + * @param literal a literal version of the error message + * @param reason std::string describing the error * @see ASSERT_PRECONDITION, ASSERT_POSTCONDITION, ASSERT_ARITHMETIC * @see PANIC_PRECONDITION, PANIC_POSTCONDITION, PANIC_ARITHMETIC * @see setMode() */ - static inline void panic(char const* function, char const* file, int line, const std::string& s) - UTILS_NORETURN { - panic(function, file, line, s.c_str()); - } + static inline void panic( + char const* function, char const* file, int line, char const* literal, + std::string reason) UTILS_NORETURN; protected: - /** - * Creates a Panic. - * @param reason a description of the cause of the error - */ - explicit TPanic(std::string reason); /** * Creates a Panic with extra information about the error-site. * @param function the name of the function where the error was detected * @param file the file where the above function in implemented * @param line the line in the above file where the error was detected + * @param literal a literal version of the error message * @param reason a description of the cause of the error */ - TPanic(char const* function, char const* file, int line, std::string reason); + TPanic(char const* function, char const* file, int line, char const* literal, + std::string reason); ~TPanic() override; private: void buildMessage(); - CallStack m_callstack; - std::string m_reason; - char const* const m_function = nullptr; - char const* const m_file = nullptr; - const int m_line = -1; - mutable std::string m_msg; + char const* const mFile = nullptr; // file where the panic happened + char const* const mFunction = nullptr; // function where the panic happened + int const mLine = -1; // line where the panic happened + std::string mLiteral; // reason for the panic, built only from literals + std::string mReason; // reason for the panic + mutable std::string mWhat; // fully formatted reason + CallStack mCallstack; }; namespace details { @@ -421,6 +448,7 @@ class UTILS_PUBLIC PreconditionPanic : public TPanic { // e.g.: invalid arguments using TPanic::TPanic; friend class TPanic; + constexpr static auto type = "Precondition"; }; /** @@ -434,6 +462,7 @@ class UTILS_PUBLIC PostconditionPanic : public TPanic { // e.g.: dead-lock would occur, arithmetic errors using TPanic::TPanic; friend class TPanic; + constexpr static auto type = "Postcondition"; }; /** @@ -447,8 +476,74 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic { // e.g.: underflow, overflow, internal computations errors using TPanic::TPanic; friend class TPanic; + constexpr static auto type = "Arithmetic"; +}; + +namespace details { + +struct Voidify final { + template + void operator&&(const T&) const&& {} +}; + +class UTILS_PUBLIC PanicStream { +public: + PanicStream( + char const* function, + char const* file, + int line, + char const* message) noexcept; + + ~PanicStream(); + + PanicStream& operator<<(short value) noexcept; + PanicStream& operator<<(unsigned short value) noexcept; + + PanicStream& operator<<(char value) noexcept; + PanicStream& operator<<(unsigned char value) noexcept; + + PanicStream& operator<<(int value) noexcept; + PanicStream& operator<<(unsigned int value) noexcept; + + PanicStream& operator<<(long value) noexcept; + PanicStream& operator<<(unsigned long value) noexcept; + + PanicStream& operator<<(long long value) noexcept; + PanicStream& operator<<(unsigned long long value) noexcept; + + PanicStream& operator<<(float value) noexcept; + PanicStream& operator<<(double value) noexcept; + PanicStream& operator<<(long double value) noexcept; + + PanicStream& operator<<(bool value) noexcept; + + PanicStream& operator<<(const void* value) noexcept; + + PanicStream& operator<<(const char* string) noexcept; + PanicStream& operator<<(const unsigned char* string) noexcept; + + PanicStream& operator<<(std::string const& s) noexcept; + PanicStream& operator<<(std::string_view const& s) noexcept; + +protected: + io::sstream mStream; + char const* mFunction; + char const* mFile; + int mLine; + char const* mLiteral; }; +template +class TPanicStream : public PanicStream { +public: + using PanicStream::PanicStream; + ~TPanicStream() noexcept(false) UTILS_NORETURN { + T::panic(mFunction, mFile, mLine, mLiteral, mStream.c_str()); + } +}; + +} // namespace details + // ----------------------------------------------------------------------------------------------- } // namespace utils @@ -460,37 +555,70 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic { # define PANIC_FUNCTION __func__ #endif + +#define FILAMENT_CHECK_CONDITION_IMPL(cond) \ + switch (0) \ + case 0: \ + default: \ + UTILS_LIKELY(cond) ? (void)0 : ::utils::details::Voidify()&& + +#define FILAMENT_PANIC_IMPL(message, TYPE) \ + ::utils::details::TPanicStream<::utils::TYPE>(PANIC_FUNCTION, PANIC_FILE(__FILE__), __LINE__, message) + +#ifndef FILAMENT_CHECK_PRECONDITION +#define FILAMENT_CHECK_PRECONDITION(condition) \ + FILAMENT_CHECK_CONDITION_IMPL(condition) FILAMENT_PANIC_IMPL(#condition, PreconditionPanic) +#endif + +#ifndef FILAMENT_CHECK_POSTCONDITION +#define FILAMENT_CHECK_POSTCONDITION(condition) \ + FILAMENT_CHECK_CONDITION_IMPL(condition) FILAMENT_PANIC_IMPL(#condition, PostconditionPanic) +#endif + +#ifndef FILAMENT_CHECK_ARITHMETIC +#define FILAMENT_CHECK_ARITHMETIC(condition) \ + FILAMENT_CHECK_CONDITION_IMPL(condition) FILAMENT_PANIC_IMPL(#condition, ArithmeticPanic) +#endif + +#define PANIC_PRECONDITION_IMPL(cond, format, ...) \ + ::utils::PreconditionPanic::panic(PANIC_FUNCTION, \ + PANIC_FILE(__FILE__), __LINE__, #cond, format, ##__VA_ARGS__) + +#define PANIC_POSTCONDITION_IMPL(cond, format, ...) \ + ::utils::PostconditionPanic::panic(PANIC_FUNCTION, \ + PANIC_FILE(__FILE__), __LINE__, #cond, format, ##__VA_ARGS__) + +#define PANIC_ARITHMETIC_IMPL(cond, format, ...) \ + ::utils::ArithmeticPanic::panic(PANIC_FUNCTION, \ + PANIC_FILE(__FILE__), __LINE__, #cond, format, ##__VA_ARGS__) + +#define PANIC_LOG_IMPL(cond, format, ...) \ + ::utils::details::panicLog(PANIC_FUNCTION, \ + PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__) + /** * PANIC_PRECONDITION is a macro that reports a PreconditionPanic * @param format printf-style string describing the error in more details */ -#define PANIC_PRECONDITION(format, ...) \ - ::utils::PreconditionPanic::panic(PANIC_FUNCTION, \ - PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__) +#define PANIC_PRECONDITION(format, ...) PANIC_PRECONDITION_IMPL(format, format, ##__VA_ARGS__) /** * PANIC_POSTCONDITION is a macro that reports a PostconditionPanic * @param format printf-style string describing the error in more details */ -#define PANIC_POSTCONDITION(format, ...) \ - ::utils::PostconditionPanic::panic(PANIC_FUNCTION, \ - PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__) +#define PANIC_POSTCONDITION(format, ...) PANIC_POSTCONDITION_IMPL(format, format, ##__VA_ARGS__) /** * PANIC_ARITHMETIC is a macro that reports a ArithmeticPanic * @param format printf-style string describing the error in more details */ -#define PANIC_ARITHMETIC(format, ...) \ - ::utils::ArithmeticPanic::panic(PANIC_FUNCTION, \ - PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__) +#define PANIC_ARITHMETIC(format, ...) PANIC_ARITHMETIC_IMPL(format, format, ##__VA_ARGS__) /** * PANIC_LOG is a macro that logs a Panic, and continues as usual. * @param format printf-style string describing the error in more details */ -#define PANIC_LOG(format, ...) \ - ::utils::details::panicLog(PANIC_FUNCTION, \ - PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__) +#define PANIC_LOG(format, ...) PANIC_LOG_IMPL(format, format, ##__VA_ARGS__) /** * @ingroup errors @@ -501,14 +629,14 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic { * @param format printf-style string describing the error in more details */ #define ASSERT_PRECONDITION(cond, format, ...) \ - (!UTILS_LIKELY(cond) ? PANIC_PRECONDITION(format, ##__VA_ARGS__) : (void)0) + (!UTILS_LIKELY(cond) ? PANIC_PRECONDITION_IMPL(cond, format, ##__VA_ARGS__) : (void)0) #if defined(UTILS_EXCEPTIONS) || !defined(NDEBUG) #define ASSERT_PRECONDITION_NON_FATAL(cond, format, ...) \ - (!UTILS_LIKELY(cond) ? PANIC_PRECONDITION(format, ##__VA_ARGS__), false : true) + (!UTILS_LIKELY(cond) ? PANIC_PRECONDITION_IMPL(cond, format, ##__VA_ARGS__), false : true) #else #define ASSERT_PRECONDITION_NON_FATAL(cond, format, ...) \ - (!UTILS_LIKELY(cond) ? PANIC_LOG(format, ##__VA_ARGS__), false : true) + (!UTILS_LIKELY(cond) ? PANIC_LOG_IMPL(cond, format, ##__VA_ARGS__), false : true) #endif @@ -529,14 +657,14 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic { * @endcode */ #define ASSERT_POSTCONDITION(cond, format, ...) \ - (!UTILS_LIKELY(cond) ? PANIC_POSTCONDITION(format, ##__VA_ARGS__) : (void)0) + (!UTILS_LIKELY(cond) ? PANIC_POSTCONDITION_IMPL(cond, format, ##__VA_ARGS__) : (void)0) #if defined(UTILS_EXCEPTIONS) || !defined(NDEBUG) #define ASSERT_POSTCONDITION_NON_FATAL(cond, format, ...) \ - (!UTILS_LIKELY(cond) ? PANIC_POSTCONDITION(format, ##__VA_ARGS__), false : true) + (!UTILS_LIKELY(cond) ? PANIC_POSTCONDITION_IMPL(cond, format, ##__VA_ARGS__), false : true) #else #define ASSERT_POSTCONDITION_NON_FATAL(cond, format, ...) \ - (!UTILS_LIKELY(cond) ? PANIC_LOG(format, ##__VA_ARGS__), false : true) + (!UTILS_LIKELY(cond) ? PANIC_LOG_IMPL(cond, format, ##__VA_ARGS__), false : true) #endif /** @@ -557,14 +685,14 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic { * @endcode */ #define ASSERT_ARITHMETIC(cond, format, ...) \ - (!(cond) ? PANIC_ARITHMETIC(format, ##__VA_ARGS__) : (void)0) + (!(cond) ? PANIC_ARITHMETIC_IMPL(cond, format, ##__VA_ARGS__) : (void)0) #if defined(UTILS_EXCEPTIONS) || !defined(NDEBUG) #define ASSERT_ARITHMETIC_NON_FATAL(cond, format, ...) \ - (!UTILS_LIKELY(cond) ? PANIC_ARITHMETIC(format, ##__VA_ARGS__), false : true) + (!UTILS_LIKELY(cond) ? PANIC_ARITHMETIC_IMPL(cond, format, ##__VA_ARGS__), false : true) #else #define ASSERT_ARITHMETIC_NON_FATAL(cond, format, ...) \ - (!UTILS_LIKELY(cond) ? PANIC_LOG(format, ##__VA_ARGS__), false : true) + (!UTILS_LIKELY(cond) ? PANIC_LOG_IMPL(cond, format, ##__VA_ARGS__), false : true) #endif /** @@ -588,6 +716,7 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic { * } * @endcode */ -#define ASSERT_DESTRUCTOR(cond, format, ...) (!(cond) ? PANIC_LOG(format, ##__VA_ARGS__) : (void)0) +#define ASSERT_DESTRUCTOR(cond, format, ...) \ + (!UTILS_LIKELY(cond) ? PANIC_LOG_IMPL(cond, format, ##__VA_ARGS__) : (void)0) #endif // TNT_UTILS_PANIC_H diff --git a/package/ios/libs/filament/include/utils/StructureOfArrays.h b/package/ios/libs/filament/include/utils/StructureOfArrays.h index a4309584..c0b2315e 100644 --- a/package/ios/libs/filament/include/utils/StructureOfArrays.h +++ b/package/ios/libs/filament/include/utils/StructureOfArrays.h @@ -368,7 +368,7 @@ class StructureOfArraysBase { size_t last = mSize++; // Fold expression on the comma operator ([&]{ - new(std::get(mArrays) + last) Elements{std::get(args)}; + new(std::get(mArrays) + last) Elements{std::get(std::forward(args))}; }() , ...); } @@ -513,7 +513,7 @@ class StructureOfArraysBase { return (soa.elementAt(i) = other); } UTILS_ALWAYS_INLINE Type const& operator = (Type&& other) noexcept { - return (soa.elementAt(i) = other); + return (soa.elementAt(i) = std::forward(other)); } // comparisons UTILS_ALWAYS_INLINE bool operator==(Type const& other) const { diff --git a/package/ios/libs/filament/include/utils/algorithm.h b/package/ios/libs/filament/include/utils/algorithm.h index ea5ca44f..7a747b84 100644 --- a/package/ios/libs/filament/include/utils/algorithm.h +++ b/package/ios/libs/filament/include/utils/algorithm.h @@ -22,6 +22,7 @@ #include // for std::enable_if #include +#include #include namespace utils { @@ -43,9 +44,15 @@ constexpr inline T clz(T x) noexcept { static_assert(sizeof(T) * CHAR_BIT <= 128, "details::clz() only support up to 128 bits"); x |= (x >> 1u); x |= (x >> 2u); - x |= (x >> 4u); - x |= (x >> 8u); - x |= (x >> 16u); + if constexpr (sizeof(T) * CHAR_BIT >= 8) { // just to silence compiler warning + x |= (x >> 4u); + } + if constexpr (sizeof(T) * CHAR_BIT >= 16) { // just to silence compiler warning + x |= (x >> 8u); + } + if constexpr (sizeof(T) * CHAR_BIT >= 32) { // just to silence compiler warning + x |= (x >> 16u); + } if constexpr (sizeof(T) * CHAR_BIT >= 64) { // just to silence compiler warning x |= (x >> 32u); } @@ -67,11 +74,15 @@ constexpr inline T ctz(T x) noexcept { x &= -x; #endif if (x) c--; - if (sizeof(T) * CHAR_BIT >= 64) { + if constexpr (sizeof(T) * CHAR_BIT >= 64) { if (x & T(0x00000000FFFFFFFF)) c -= 32; } - if (x & T(0x0000FFFF0000FFFF)) c -= 16; - if (x & T(0x00FF00FF00FF00FF)) c -= 8; + if constexpr (sizeof(T) * CHAR_BIT >= 32) { + if (x & T(0x0000FFFF0000FFFF)) c -= 16; + } + if constexpr (sizeof(T) * CHAR_BIT >= 16) { + if (x & T(0x00FF00FF00FF00FF)) c -= 8; + } if (x & T(0x0F0F0F0F0F0F0F0F)) c -= 4; if (x & T(0x3333333333333333)) c -= 2; if (x & T(0x5555555555555555)) c -= 1; @@ -80,6 +91,24 @@ constexpr inline T ctz(T x) noexcept { } // namespace details +constexpr inline UTILS_PUBLIC UTILS_PURE +unsigned int UTILS_ALWAYS_INLINE clz(unsigned char x) noexcept { +#if __has_builtin(__builtin_clz) + return __builtin_clz((unsigned int)x) - 24; +#else + return details::clz(x); +#endif +} + +constexpr inline UTILS_PUBLIC UTILS_PURE +unsigned int UTILS_ALWAYS_INLINE clz(unsigned short x) noexcept { +#if __has_builtin(__builtin_clz) + return __builtin_clz((unsigned int)x) - 16; +#else + return details::clz(x); +#endif +} + constexpr inline UTILS_PUBLIC UTILS_PURE unsigned int UTILS_ALWAYS_INLINE clz(unsigned int x) noexcept { #if __has_builtin(__builtin_clz) @@ -107,6 +136,24 @@ unsigned long long UTILS_ALWAYS_INLINE clz(unsigned long long x) noexcept { #endif } +constexpr inline UTILS_PUBLIC UTILS_PURE +unsigned int UTILS_ALWAYS_INLINE ctz(unsigned char x) noexcept { +#if __has_builtin(__builtin_ctz) + return __builtin_ctz(x); +#else + return details::ctz(x); +#endif +} + +constexpr inline UTILS_PUBLIC UTILS_PURE +unsigned int UTILS_ALWAYS_INLINE ctz(unsigned short x) noexcept { +#if __has_builtin(__builtin_ctz) + return __builtin_ctz(x); +#else + return details::ctz(x); +#endif +} + constexpr inline UTILS_PUBLIC UTILS_PURE unsigned int UTILS_ALWAYS_INLINE ctz(unsigned int x) noexcept { #if __has_builtin(__builtin_ctz) @@ -134,6 +181,24 @@ unsigned long long UTILS_ALWAYS_INLINE ctz(unsigned long long x) noexcept { #endif } +constexpr inline UTILS_PUBLIC UTILS_PURE +unsigned int UTILS_ALWAYS_INLINE popcount(unsigned char x) noexcept { +#if __has_builtin(__builtin_popcount) + return __builtin_popcount(x); +#else + return details::popcount(x); +#endif +} + +constexpr inline UTILS_PUBLIC UTILS_PURE +unsigned int UTILS_ALWAYS_INLINE popcount(unsigned short x) noexcept { +#if __has_builtin(__builtin_popcount) + return __builtin_popcount(x); +#else + return details::popcount(x); +#endif +} + constexpr inline UTILS_PUBLIC UTILS_PURE unsigned int UTILS_ALWAYS_INLINE popcount(unsigned int x) noexcept { #if __has_builtin(__builtin_popcount) @@ -161,11 +226,6 @@ unsigned long long UTILS_ALWAYS_INLINE popcount(unsigned long long x) noexcept { #endif } -constexpr inline UTILS_PUBLIC UTILS_PURE -uint8_t UTILS_ALWAYS_INLINE popcount(uint8_t x) noexcept { - return (uint8_t)popcount((unsigned int)x); -} - template::value && std::is_unsigned::value>> constexpr inline UTILS_PUBLIC UTILS_PURE diff --git a/package/ios/libs/filament/include/utils/bitset.h b/package/ios/libs/filament/include/utils/bitset.h index 281e5dfc..8844fdb8 100644 --- a/package/ios/libs/filament/include/utils/bitset.h +++ b/package/ios/libs/filament/include/utils/bitset.h @@ -60,6 +60,11 @@ class UTILS_PUBLIC bitset { std::fill(std::begin(storage), std::end(storage), 0); } + template> + explicit bitset(U value) noexcept { + storage[0] = value; + } + T getBitsAt(size_t n) const noexcept { assert_invariant(n +#include + +#include + +namespace utils::io { + +class UTILS_PUBLIC sstream : public ostream { +public: + ostream& flush() noexcept override; + const char* c_str() const noexcept; + size_t length() const noexcept; +}; + +} // namespace utils::io + +#endif // TNT_UTILS_SSTREAM_H diff --git a/package/package.json b/package/package.json index 852d0e36..46ebe86e 100644 --- a/package/package.json +++ b/package/package.json @@ -33,7 +33,7 @@ "clean": "rm -rf android/build example/android/build example/android/app/build example/ios/build lib", "prepare": "git submodule update --init --recursive && yarn patch-filament && bob build", "update-submodule": "git submodule update --remote --merge", - "patch-filament": "cd ../filament ; git apply ../package/filament_animator_feat.patch ; git apply ../package/filament_material_instance_getter.patch ; git apply ../package/filament_ios_simulator.patch ; cd ../package", + "patch-filament": "cd ../filament ; git apply ../package/filament_animator_feat.patch ; git apply ../package/filament_ios_simulator.patch ; cd ../package", "build-filament": "yarn patch-filament && scripts/build-filament.sh", "build-filament:release": "yarn build-filament release", "build-filament:debug": "yarn build-filament debug",