Skip to content

Commit

Permalink
Merge branch 'rc/1.54.1' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
z3moon committed Aug 27, 2024
2 parents c1a3450 + eb12e06 commit bce91c5
Show file tree
Hide file tree
Showing 54 changed files with 654 additions and 253 deletions.
2 changes: 2 additions & 0 deletions NEW_RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ for next branch cut* header.
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).

## Release notes for next branch cut

- Add a `name` API to Filament objects for debugging handle use-after-free assertions
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.54.0'
implementation 'com.google.android.filament:filament-android:1.54.1'
}
```

Expand All @@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
iOS projects can use CocoaPods to install the latest release:

```shell
pod 'Filament', '~> 1.54.0'
pod 'Filament', '~> 1.54.1'
```

### Snapshots
Expand Down
3 changes: 3 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ A new header is inserted each time a *tag* is created.
Instead, if you are authoring a PR for the main branch, add your release note to
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).

## v1.54.1


## v1.54.0

- materials: add a new `stereoscopicType` material parameter. [⚠️ **New Material Version**]
Expand Down
2 changes: 1 addition & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.54.0
VERSION_NAME=1.54.1

POM_DESCRIPTION=Real-time physically based rendering engine for Android.

Expand Down
1 change: 1 addition & 0 deletions filament/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ set(SRCS
src/Engine.cpp
src/Exposure.cpp
src/Fence.cpp
src/FilamentBuilder.cpp
src/FrameInfo.cpp
src/FrameSkipper.cpp
src/Froxelizer.cpp
Expand Down
4 changes: 4 additions & 0 deletions filament/backend/include/private/backend/DriverAPI.inc
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ DECL_DRIVER_API_0(finish)
// reset state tracking, if the driver does any state tracking (e.g. GL)
DECL_DRIVER_API_0(resetState)

DECL_DRIVER_API_N(setDebugTag,
backend::HandleBase::HandleId, handleId,
utils::CString, tag)

/*
* Creating driver objects
* -----------------------
Expand Down
38 changes: 35 additions & 3 deletions filament/backend/include/private/backend/HandleAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@
#include <backend/Handle.h>

#include <utils/Allocator.h>
#include <utils/CString.h>
#include <utils/Log.h>
#include <utils/Panic.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/ostream.h>
#include <utils/Panic.h>

#include <tsl/robin_map.h>

Expand Down Expand Up @@ -173,8 +174,10 @@ class HandleAllocator {
uint8_t const age = (tag & HANDLE_AGE_MASK) >> HANDLE_AGE_SHIFT;
auto const pNode = static_cast<typename Allocator::Node*>(p);
uint8_t const expectedAge = pNode[-1].age;
FILAMENT_CHECK_POSTCONDITION(expectedAge == age) <<
"use-after-free of Handle with id=" << handle.getId();
// getHandleTag() is only called if the check fails.
FILAMENT_CHECK_POSTCONDITION(expectedAge == age)
<< "use-after-free of Handle with id=" << handle.getId()
<< ", tag=" << getHandleTag(handle.getId()).c_str_safe();
}
}

Expand All @@ -201,6 +204,34 @@ class HandleAllocator {
return handle_cast<Dp>(const_cast<Handle<B>&>(handle));
}

void associateTagToHandle(HandleBase::HandleId id, utils::CString&& tag) noexcept {
// TODO: for now, only pool handles check for use-after-free, so we only keep tags for
// those
if (isPoolHandle(id)) {
// Truncate the tag's age to N bits.
constexpr uint8_t N = 2; // support a history of 4 tags
constexpr uint8_t mask = (1 << N) - 1;

uint8_t const age = (id & HANDLE_AGE_MASK) >> HANDLE_AGE_SHIFT;
uint8_t const newAge = age & mask;
uint32_t const key = (id & ~HANDLE_AGE_MASK) | (newAge << HANDLE_AGE_SHIFT);

// This line is the costly part. In the future, we could potentially use a custom
// allocator.
mDebugTags[key] = std::move(tag);
}
}

utils::CString getHandleTag(HandleBase::HandleId id) const noexcept {
if (!isPoolHandle(id)) {
return "(no tag)";
}
if (auto pos = mDebugTags.find(id); pos != mDebugTags.end()) {
return pos->second;
}
return "(no tag)";
}

private:

template<typename D>
Expand Down Expand Up @@ -363,6 +394,7 @@ class HandleAllocator {
// Below is only used when running out of space in the HandleArena
mutable utils::Mutex mLock;
tsl::robin_map<HandleBase::HandleId, void*> mOverflowMap;
tsl::robin_map<HandleBase::HandleId, utils::CString> mDebugTags;
HandleBase::HandleId mId = 0;
bool mUseAfterFreeCheckDisabled = false;
};
Expand Down
3 changes: 3 additions & 0 deletions filament/backend/src/HandleAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ HandleAllocator<P0, P1, P2>::HandleAllocator(const char* name, size_t size,
bool disableUseAfterFreeCheck) noexcept
: mHandleArena(name, size, disableUseAfterFreeCheck),
mUseAfterFreeCheckDisabled(disableUseAfterFreeCheck) {
// Reserve initial space for debug tags. This prevents excessive calls to malloc when the first
// few tags are set.
mDebugTags.reserve(512);
}

template <size_t P0, size_t P1, size_t P2>
Expand Down
4 changes: 4 additions & 0 deletions filament/backend/src/metal/MetalDriver.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2061,6 +2061,10 @@
void MetalDriver::resetState(int) {
}

void MetalDriver::setDebugTag(HandleBase::HandleId handleId, utils::CString tag) {
mHandleAllocator.associateTagToHandle(handleId, std::move(tag));
}

void MetalDriver::runAtNextTick(const std::function<void()>& fn) noexcept {
std::lock_guard<std::mutex> const lock(mTickOpsLock);
mTickOps.push_back(fn);
Expand Down
3 changes: 3 additions & 0 deletions filament/backend/src/noop/NoopDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,4 +388,7 @@ void NoopDriver::endTimerQuery(Handle<HwTimerQuery> tqh) {
void NoopDriver::resetState(int) {
}

void NoopDriver::setDebugTag(HandleBase::HandleId handleId, utils::CString tag) {
}

} // namespace filament
4 changes: 4 additions & 0 deletions filament/backend/src/opengl/OpenGLDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2210,6 +2210,10 @@ void OpenGLDriver::makeCurrent(Handle<HwSwapChain> schDraw, Handle<HwSwapChain>
// Updating driver objects
// ------------------------------------------------------------------------------------------------

void OpenGLDriver::setDebugTag(HandleBase::HandleId handleId, utils::CString tag) {
mHandleAllocator.associateTagToHandle(handleId, std::move(tag));
}

void OpenGLDriver::setVertexBufferObject(Handle<HwVertexBuffer> vbh,
uint32_t index, Handle<HwBufferObject> boh) {
DEBUG_MARKER()
Expand Down
4 changes: 4 additions & 0 deletions filament/backend/src/vulkan/VulkanDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2032,6 +2032,10 @@ void VulkanDriver::debugCommandBegin(CommandStream* cmds, bool synchronous, cons
void VulkanDriver::resetState(int) {
}

void VulkanDriver::setDebugTag(HandleBase::HandleId handleId, utils::CString tag) {
mResourceAllocator.associateHandle(handleId, std::move(tag));
}

// explicit instantiation of the Dispatcher
template class ConcreteDispatcher<VulkanDriver>;

Expand Down
4 changes: 4 additions & 0 deletions filament/backend/src/vulkan/VulkanResourceAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ class VulkanResourceAllocator {
mHandleAllocatorImpl.deallocate(handle, obj);
}

inline void associateHandle(HandleBase::HandleId id, utils::CString&& tag) noexcept {
mHandleAllocatorImpl.associateTagToHandle(id, std::move(tag));
}

private:
AllocatorImpl mHandleAllocatorImpl;

Expand Down
17 changes: 16 additions & 1 deletion filament/include/filament/BufferObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class UTILS_PUBLIC BufferObject : public FilamentAPI {
using BufferDescriptor = backend::BufferDescriptor;
using BindingType = backend::BufferObjectBinding;

class Builder : public BuilderBase<BuilderDetails> {
class Builder : public BuilderBase<BuilderDetails>, public BuilderNameMixin<Builder> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Expand All @@ -78,6 +78,21 @@ class UTILS_PUBLIC BufferObject : public FilamentAPI {
*/
Builder& bindingType(BindingType bindingType) noexcept;

/**
* Associate an optional name with this BufferObject for debugging purposes.
*
* name will show in error messages and should be kept as short as possible. The name is
* truncated to a maximum of 128 characters.
*
* The name string is copied during this method so clients may free its memory after
* the function returns.
*
* @param name A string to identify this BufferObject
* @param len Length of name, should be less than or equal to 128
* @return This Builder, for chaining calls.
*/
// Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept; // inherited

/**
* Creates the BufferObject and returns a pointer to it. After creation, the buffer
* object is uninitialized. Use BufferObject::setBuffer() to initialize it.
Expand Down
17 changes: 17 additions & 0 deletions filament/include/filament/FilamentAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <utils/compiler.h>
#include <utils/PrivateImplementation.h>
#include <utils/CString.h>

#include <stddef.h>

Expand Down Expand Up @@ -54,6 +55,22 @@ class UTILS_PUBLIC FilamentAPI {
template<typename T>
using BuilderBase = utils::PrivateImplementation<T>;

void builderMakeName(utils::CString& outName, const char* name, size_t len) noexcept;

template <typename Builder>
class UTILS_PUBLIC BuilderNameMixin {
public:
Builder& name(const char* name, size_t len) noexcept {
builderMakeName(mName, name, len);
return static_cast<Builder&>(*this);
}

utils::CString const& getName() const noexcept { return mName; }

private:
utils::CString mName;
};

} // namespace filament

#endif // TNT_FILAMENT_FILAMENTAPI_H
17 changes: 16 additions & 1 deletion filament/include/filament/IndexBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class UTILS_PUBLIC IndexBuffer : public FilamentAPI {
UINT = uint8_t(backend::ElementType::UINT), //!< 32-bit indices
};

class Builder : public BuilderBase<BuilderDetails> {
class Builder : public BuilderBase<BuilderDetails>, public BuilderNameMixin<Builder> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Expand All @@ -83,6 +83,21 @@ class UTILS_PUBLIC IndexBuffer : public FilamentAPI {
*/
Builder& bufferType(IndexType indexType) noexcept;

/**
* Associate an optional name with this IndexBuffer for debugging purposes.
*
* name will show in error messages and should be kept as short as possible. The name is
* truncated to a maximum of 128 characters.
*
* The name string is copied during this method so clients may free its memory after
* the function returns.
*
* @param name A string to identify this IndexBuffer
* @param len Length of name, should be less than or equal to 128
* @return This Builder, for chaining calls.
*/
// Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept; // inherited

/**
* Creates the IndexBuffer object and returns a pointer to it. After creation, the index
* buffer is uninitialized. Use IndexBuffer::setBuffer() to initialize the IndexBuffer.
Expand Down
17 changes: 16 additions & 1 deletion filament/include/filament/InstanceBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class UTILS_PUBLIC InstanceBuffer : public FilamentAPI {
struct BuilderDetails;

public:
class Builder : public BuilderBase<BuilderDetails> {
class Builder : public BuilderBase<BuilderDetails>, public BuilderNameMixin<Builder> {
friend struct BuilderDetails;

public:
Expand Down Expand Up @@ -70,6 +70,21 @@ class UTILS_PUBLIC InstanceBuffer : public FilamentAPI {
*/
Builder& localTransforms(math::mat4f const* UTILS_NULLABLE localTransforms) noexcept;

/**
* Associate an optional name with this InstanceBuffer for debugging purposes.
*
* name will show in error messages and should be kept as short as possible. The name is
* truncated to a maximum of 128 characters.
*
* The name string is copied during this method so clients may free its memory after
* the function returns.
*
* @param name A string to identify this InstanceBuffer
* @param len Length of name, should be less than or equal to 128
* @return This Builder, for chaining calls.
*/
// Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept; // inherited

/**
* Creates the InstanceBuffer object and returns a pointer to it.
*/
Expand Down
17 changes: 16 additions & 1 deletion filament/include/filament/MorphTargetBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class UTILS_PUBLIC MorphTargetBuffer : public FilamentAPI {
struct BuilderDetails;

public:
class Builder : public BuilderBase<BuilderDetails> {
class Builder : public BuilderBase<BuilderDetails>, public BuilderNameMixin<Builder> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Expand All @@ -63,6 +63,21 @@ class UTILS_PUBLIC MorphTargetBuffer : public FilamentAPI {
*/
Builder& count(size_t count) noexcept;

/**
* Associate an optional name with this MorphTargetBuffer for debugging purposes.
*
* name will show in error messages and should be kept as short as possible. The name is
* truncated to a maximum of 128 characters.
*
* The name string is copied during this method so clients may free its memory after
* the function returns.
*
* @param name A string to identify this MorphTargetBuffer
* @param len Length of name, should be less than or equal to 128
* @return This Builder, for chaining calls.
*/
// Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept; // inherited

/**
* Creates the MorphTargetBuffer object and returns a pointer to it.
*
Expand Down
17 changes: 16 additions & 1 deletion filament/include/filament/SkinningBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class UTILS_PUBLIC SkinningBuffer : public FilamentAPI {
struct BuilderDetails;

public:
class Builder : public BuilderBase<BuilderDetails> {
class Builder : public BuilderBase<BuilderDetails>, public BuilderNameMixin<Builder> {
friend struct BuilderDetails;
public:
Builder() noexcept;
Expand Down Expand Up @@ -69,6 +69,21 @@ class UTILS_PUBLIC SkinningBuffer : public FilamentAPI {
*/
Builder& initialize(bool initialize = true) noexcept;

/**
* Associate an optional name with this SkinningBuffer for debugging purposes.
*
* name will show in error messages and should be kept as short as possible. The name is
* truncated to a maximum of 128 characters.
*
* The name string is copied during this method so clients may free its memory after
* the function returns.
*
* @param name A string to identify this SkinningBuffer
* @param len Length of name, should be less than or equal to 128
* @return This Builder, for chaining calls.
*/
// Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept; // inherited

/**
* Creates the SkinningBuffer object and returns a pointer to it.
*
Expand Down
Loading

0 comments on commit bce91c5

Please sign in to comment.