fix exceptions (#9281)

This commit is contained in:
Mathias Agopian
2025-10-02 16:22:01 -07:00
committed by GitHub
parent bc794bbf7b
commit b22ff3bebb
54 changed files with 166 additions and 149 deletions

View File

@@ -236,7 +236,7 @@ public:
* @return nullptr on failure, or a pointer to the newly created driver.
*/
virtual Driver* UTILS_NULLABLE createDriver(void* UTILS_NULLABLE sharedContext,
const DriverConfig& driverConfig) noexcept = 0;
const DriverConfig& driverConfig) = 0;
/**
* Processes the platform's event queue when called from its primary event-handling thread.

View File

@@ -118,7 +118,7 @@ public:
Program& multiview(bool multiview) noexcept;
// For ES2 support only...
Program& uniforms(uint32_t index, utils::CString name, UniformInfo uniforms) noexcept;
Program& uniforms(uint32_t index, utils::CString name, UniformInfo uniforms);
Program& attributes(AttributesInfo attributes) noexcept;
//

View File

@@ -112,7 +112,7 @@ public:
*
*/
virtual SwapChain* UTILS_NULLABLE createSwapChain(
void* UTILS_NULLABLE nativeWindow, uint64_t flags) noexcept = 0;
void* UTILS_NULLABLE nativeWindow, uint64_t flags) = 0;
/**
* Called by the driver create a headless SwapChain.
@@ -126,7 +126,7 @@ public:
* A void* might be enough.
*/
virtual SwapChain* UTILS_NULLABLE createSwapChain(
uint32_t width, uint32_t height, uint64_t flags) noexcept = 0;
uint32_t width, uint32_t height, uint64_t flags) = 0;
/**
* Called by the driver to destroys the SwapChain

View File

@@ -40,7 +40,7 @@ protected:
// Platform Interface
Driver* createDriver(void* sharedContext,
const DriverConfig& driverConfig) noexcept override;
const DriverConfig& driverConfig) override;
// Currently returns 0
int getOSVersion() const noexcept override;

View File

@@ -38,7 +38,7 @@ public:
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const DriverConfig& driverConfig) noexcept override;
const DriverConfig& driverConfig) override;
int getOSVersion() const noexcept final { return 0; }

View File

@@ -80,7 +80,7 @@ protected:
* Initializes EGL, creates the OpenGL context and returns a concrete Driver implementation
* that supports OpenGL/OpenGL ES.
*/
Driver* createDriver(void* sharedContext, const DriverConfig& driverConfig) noexcept override;
Driver* createDriver(void* sharedContext, const DriverConfig& driverConfig) override;
/**
* This returns zero. This method can be overridden to return something more useful.
@@ -101,8 +101,8 @@ protected:
bool isSRGBSwapChainSupported() const noexcept override;
bool isMSAASwapChainSupported(uint32_t samples) const noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
bool isSwapChainProtected(SwapChain* swapChain) noexcept override;

View File

@@ -80,7 +80,7 @@ protected:
int getOSVersion() const noexcept override;
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
const Platform::DriverConfig& driverConfig) override;
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface

View File

@@ -29,7 +29,7 @@ public:
PlatformEGLHeadless() noexcept;
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
const Platform::DriverConfig& driverConfig) override;
protected:
bool isOpenGL() const noexcept override;

View File

@@ -39,7 +39,7 @@ protected:
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const DriverConfig& driverConfig) noexcept override;
const DriverConfig& driverConfig) override;
int getOSVersion() const noexcept final override { return 0; }

View File

@@ -36,7 +36,7 @@ public:
PlatformMetal();
~PlatformMetal() noexcept override;
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) override;
int getOSVersion() const noexcept override { return 0; }
/**

View File

@@ -43,7 +43,7 @@ protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedGLContext, const DriverConfig& driverConfig) noexcept override;
Driver* createDriver(void* sharedGLContext, const DriverConfig& driverConfig) override;
int getOSVersion() const noexcept final override { return 0; }

View File

@@ -38,7 +38,7 @@ protected:
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept override;
const Platform::DriverConfig& driverConfig) override;
int getOSVersion() const noexcept final override { return 0; }

View File

@@ -34,7 +34,7 @@ protected:
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept override;
const Platform::DriverConfig& driverConfig) override;
int getOSVersion() const noexcept override;

View File

@@ -119,7 +119,7 @@ public:
~VulkanPlatform() override;
Driver* createDriver(void* sharedContext,
Platform::DriverConfig const& driverConfig) noexcept override;
Platform::DriverConfig const& driverConfig) override;
int getOSVersion() const noexcept override {
return 0;

View File

@@ -72,7 +72,7 @@ public:
protected:
[[nodiscard]] Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
const Platform::DriverConfig& driverConfig) override;
private:
// returns adapter request option variations applicable for the particular

View File

@@ -61,7 +61,7 @@ class CommandBase {
protected:
using Execute = Dispatcher::Execute;
constexpr explicit CommandBase(Execute execute) noexcept : mExecute(execute) {}
constexpr explicit CommandBase(Execute const execute) noexcept : mExecute(execute) {}
public:
// alignment of all Commands in the CommandStream
@@ -70,7 +70,7 @@ public:
}
// executes this command and returns the next one
inline CommandBase* execute(Driver& driver) {
CommandBase* execute(Driver& driver) {
// returning the next command by output parameter allows the compiler to perform the
// tail-call optimization in the function called by mExecute, however that comes at
// a cost here (writing and reading the stack at each iteration), in the end it's
@@ -80,7 +80,7 @@ public:
return reinterpret_cast<CommandBase*>(reinterpret_cast<intptr_t>(this) + next);
}
inline ~CommandBase() noexcept = default;
~CommandBase() noexcept = default;
private:
Execute mExecute;
@@ -135,7 +135,7 @@ struct CommandType<void (Driver::*)(ARGS...)> {
public:
template<typename M, typename D>
static inline void execute(M&& method, D&& driver, CommandBase* base, intptr_t* next) {
static void execute(M&& method, D&& driver, CommandBase* base, intptr_t* next) {
Command* self = static_cast<Command*>(base);
*next = align(sizeof(Command));
#if DEBUG_COMMAND_STREAM
@@ -147,15 +147,15 @@ struct CommandType<void (Driver::*)(ARGS...)> {
}
// A command can be moved
inline Command(Command&& rhs) noexcept = default;
Command(Command&& rhs) noexcept = default;
template<typename... A>
inline explicit constexpr Command(Execute execute, A&& ... args)
explicit constexpr Command(Execute const execute, A&& ... args) noexcept
: CommandBase(execute), mArgs(std::forward<A>(args)...) {
}
// placement new declared as "throw" to avoid the compiler's null-check
inline void* operator new(std::size_t, void* ptr) {
void* operator new(std::size_t, void* ptr) noexcept {
assert_invariant(ptr);
return ptr;
}
@@ -171,8 +171,9 @@ class CustomCommand : public CommandBase {
std::function<void()> mCommand;
static void execute(Driver&, CommandBase* base, intptr_t* next);
public:
inline CustomCommand(CustomCommand&& rhs) = default;
inline explicit CustomCommand(std::function<void()> cmd)
CustomCommand(CustomCommand&& rhs) = default;
explicit CustomCommand(std::function<void()> cmd)
: CommandBase(execute), mCommand(std::move(cmd)) { }
};
@@ -184,7 +185,7 @@ class NoopCommand : public CommandBase {
*next = static_cast<NoopCommand*>(self)->mNext;
}
public:
inline constexpr explicit NoopCommand(void* next) noexcept
constexpr explicit NoopCommand(void* next) noexcept
: CommandBase(execute), mNext(intptr_t((char *)next - (char *)this)) { }
};
@@ -207,8 +208,8 @@ class CommandStream {
template<typename T>
struct AutoExecute {
T closure;
inline explicit AutoExecute(T&& closure) : closure(std::forward<T>(closure)) {}
inline ~AutoExecute() { closure(); }
explicit AutoExecute(T&& closure) : closure(std::forward<T>(closure)) {}
~AutoExecute() { closure(); }
};
public:
@@ -221,7 +222,7 @@ public:
public:
#define DECL_DRIVER_API(methodName, paramsDecl, params) \
inline void methodName(paramsDecl) { \
inline void methodName(paramsDecl) noexcept { \
DEBUG_COMMAND_BEGIN(methodName, false, params); \
using Cmd = COMMAND_TYPE(methodName); \
void* const p = allocateCommand(CommandBase::align(sizeof(Cmd))); \
@@ -230,7 +231,7 @@ public:
}
#define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params) \
inline RetType methodName(paramsDecl) { \
inline RetType methodName(paramsDecl) noexcept { \
DEBUG_COMMAND_BEGIN(methodName, true, params); \
AutoExecute callOnExit([=, this](){ \
DEBUG_COMMAND_END(methodName, true); \
@@ -239,7 +240,7 @@ public:
}
#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) \
inline RetType methodName(paramsDecl) { \
inline RetType methodName(paramsDecl) noexcept { \
DEBUG_COMMAND_BEGIN(methodName, false, params); \
RetType result = mDriver.methodName##S(); \
using Cmd = COMMAND_TYPE(methodName##R); \
@@ -255,7 +256,7 @@ public:
// This is for debugging only. Currently, CircularBuffer can only be written from a
// single thread. In debug builds we assert this condition.
// Call this first in the render loop.
inline void debugThreading() noexcept {
void debugThreading() noexcept {
#ifndef NDEBUG
mThreadId = utils::ThreadUtils::getThreadId();
#endif
@@ -281,11 +282,11 @@ public:
*/
template<typename PodType,
typename = typename std::enable_if<std::is_trivially_destructible<PodType>::value>::type>
inline PodType* allocatePod(
PodType* allocatePod(
size_t count = 1, size_t alignment = alignof(PodType)) noexcept;
private:
inline void* allocateCommand(size_t size) {
void* allocateCommand(size_t const size) noexcept {
assert_invariant(utils::ThreadUtils::isThisThread(mThreadId));
return mCurrentBuffer.allocate(size);
}

View File

@@ -70,12 +70,12 @@ private:
template<size_t P0, size_t P1, size_t P2>
class HandleAllocator : public DebugTag {
public:
HandleAllocator(const char* name, size_t size) noexcept;
HandleAllocator(const char* name, size_t size);
HandleAllocator(const char* name, size_t size,
bool disableUseAfterFreeCheck, bool disableHeapHandleTags) noexcept;
bool disableUseAfterFreeCheck, bool disableHeapHandleTags);
HandleAllocator(HandleAllocator const& rhs) = delete;
HandleAllocator& operator=(HandleAllocator const& rhs) = delete;
~HandleAllocator();
~HandleAllocator() noexcept;
/*
* Constructs a D object and returns a Handle<D>
@@ -106,7 +106,7 @@ public:
*
*/
template<typename D>
Handle<D> allocate() noexcept {
Handle<D> allocate() {
Handle<D> h{ allocateHandle<D>() };
return h;
}
@@ -342,7 +342,7 @@ private:
// allocation size this is always inlined, because all these do is to call
// allocateHandleInPool()/deallocateHandleFromPool() with the right pool size.
template<typename D>
HandleBase::HandleId allocateHandle() noexcept {
HandleBase::HandleId allocateHandle() {
constexpr size_t BUCKET_SIZE = getBucketSize<D>();
return allocateHandleInPool<BUCKET_SIZE>();
}
@@ -358,7 +358,7 @@ private:
// the code generated is not trivial (even if it's not insane either).
template<size_t SIZE>
UTILS_NOINLINE
HandleBase::HandleId allocateHandleInPool() noexcept {
HandleBase::HandleId allocateHandleInPool() {
uint8_t age;
void* p = mHandleArena.alloc(SIZE, alignof(std::max_align_t), 0, &age);
if (UTILS_LIKELY(p)) {

View File

@@ -20,7 +20,7 @@
namespace filament::backend {
CallbackManager::CallbackManager(DriverBase& driver) noexcept
CallbackManager::CallbackManager(DriverBase& driver)
: mDriver(driver), mCallbacks(1) {
}

View File

@@ -51,7 +51,7 @@ class CallbackManager {
public:
using Handle = Container::const_iterator;
explicit CallbackManager(DriverBase& driver) noexcept;
explicit CallbackManager(DriverBase& driver);
~CallbackManager() noexcept;
@@ -78,7 +78,7 @@ private:
return --mCallbacks.end();
}
Container::iterator allocateNewSlot() noexcept {
Container::iterator allocateNewSlot() {
std::lock_guard const lock(mLock);
auto curr = --mCallbacks.end();
mCallbacks.emplace_back();

View File

@@ -57,12 +57,15 @@ static void printParameterPack(io::ostream& out, const FIRST& first, const REMAI
printParameterPack(out, rest...);
}
static UTILS_NOINLINE UTILS_UNUSED std::string_view extractMethodName(std::string_view command) noexcept {
constexpr const char startPattern[] = "::Command<&filament::backend::Driver::";
static UTILS_NOINLINE UTILS_UNUSED std::string_view extractMethodName(std::string_view command) noexcept { // NOLINT(*-exception-escape)
constexpr char startPattern[] = "::Command<&filament::backend::Driver::";
auto pos = command.rfind(startPattern);
auto end = command.rfind('(');
pos += sizeof(startPattern) - 1;
return command.substr(pos, end-pos);
if (pos > command.size()) {
return { command.data(), command.size() };
}
return command.substr(pos, end-pos); // this can't throw by construction
}
// ------------------------------------------------------------------------------------------------

View File

@@ -18,7 +18,14 @@
#include <private/utils/Tracing.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <algorithm>
#include <iterator>
#include <memory>
#include <mutex>
#include <utility>
namespace filament::backend {
@@ -36,7 +43,7 @@ CompilerThreadPool::~CompilerThreadPool() noexcept {
}
void CompilerThreadPool::init(uint32_t threadCount,
ThreadSetup&& threadSetup, ThreadCleanup&& threadCleanup) noexcept {
ThreadSetup&& threadSetup, ThreadCleanup&& threadCleanup) {
auto setup = std::make_shared<ThreadSetup>(std::move(threadSetup));
auto cleanup = std::make_shared<ThreadCleanup>(std::move(threadCleanup));

View File

@@ -47,8 +47,7 @@ public:
using Job = utils::Invocable<void()>;
using ThreadSetup = utils::Invocable<void()>;
using ThreadCleanup = utils::Invocable<void()>;
void init(uint32_t threadCount,
ThreadSetup&& threadSetup, ThreadCleanup&& threadCleanup) noexcept;
void init(uint32_t threadCount, ThreadSetup&& threadSetup, ThreadCleanup&& threadCleanup);
void terminate() noexcept;
void queue(CompilerPriorityQueue priorityQueue, program_token_t const& token, Job&& job);
Job dequeue(program_token_t const& token);

View File

@@ -131,7 +131,7 @@ void DriverBase::purge() noexcept {
// ------------------------------------------------------------------------------------------------
void DriverBase::scheduleDestroySlow(BufferDescriptor&& buffer) noexcept {
void DriverBase::scheduleDestroySlow(BufferDescriptor&& buffer) {
auto const handler = buffer.getHandler();
scheduleCallback(handler, [buffer = std::move(buffer)]() {
// user callback is called when BufferDescriptor gets destroyed
@@ -140,7 +140,7 @@ void DriverBase::scheduleDestroySlow(BufferDescriptor&& buffer) noexcept {
// This is called from an async driver method so it's in the GL thread, but purge is called
// on the user thread. This is typically called 0 or 1 times per frame.
void DriverBase::scheduleRelease(AcquiredImage const& image) noexcept {
void DriverBase::scheduleRelease(AcquiredImage const& image) {
scheduleCallback(image.handler, [callback = image.callback, image = image.image, userData = image.userData]() {
callback(image, userData);
});

View File

@@ -214,15 +214,15 @@ public:
protected:
class CallbackDataDetails;
void scheduleDestroy(BufferDescriptor&& buffer) noexcept {
void scheduleDestroy(BufferDescriptor&& buffer) {
if (buffer.hasCallback()) {
scheduleDestroySlow(std::move(buffer));
}
}
void scheduleDestroySlow(BufferDescriptor&& buffer) noexcept;
void scheduleDestroySlow(BufferDescriptor&& buffer);
void scheduleRelease(AcquiredImage const& image) noexcept;
void scheduleRelease(AcquiredImage const& image);
void debugCommandBegin(CommandStream* cmds, bool synchronous, const char* methodName) noexcept override;
void debugCommandEnd(CommandStream* cmds, bool synchronous, const char* methodName) noexcept override;

View File

@@ -81,19 +81,19 @@ HandleAllocator<P0, P1, P2>::Allocator::Allocator(AreaPolicy::HeapArea const& ar
template <size_t P0, size_t P1, size_t P2>
HandleAllocator<P0, P1, P2>::HandleAllocator(const char* name, size_t size,
bool disableUseAfterFreeCheck,
bool disableHeapHandleTags) noexcept
bool disableHeapHandleTags)
: mHandleArena(name, size, disableUseAfterFreeCheck),
mUseAfterFreeCheckDisabled(disableUseAfterFreeCheck),
mHeapHandleTagsDisabled(disableHeapHandleTags) {
}
template <size_t P0, size_t P1, size_t P2>
HandleAllocator<P0, P1, P2>::HandleAllocator(const char* name, size_t size) noexcept
HandleAllocator<P0, P1, P2>::HandleAllocator(const char* name, size_t size)
: HandleAllocator(name, size, false, false) {
}
template <size_t P0, size_t P1, size_t P2>
HandleAllocator<P0, P1, P2>::~HandleAllocator() {
HandleAllocator<P0, P1, P2>::~HandleAllocator() noexcept {
auto& overflowMap = mOverflowMap;
if (!overflowMap.empty()) {
PANIC_LOG("Not all handles have been freed. Probably leaking memory.");

View File

@@ -41,37 +41,37 @@ Program& Program::operator=(Program&& rhs) noexcept = default;
Program::~Program() noexcept = default;
Program& Program::priorityQueue(CompilerPriorityQueue priorityQueue) noexcept {
Program& Program::priorityQueue(CompilerPriorityQueue const priorityQueue) noexcept {
mPriorityQueue = priorityQueue;
return *this;
}
Program& Program::diagnostics(CString const& name,
Invocable<io::ostream&(utils::CString const& name, io::ostream&)>&& logger) {
Invocable<io::ostream&(CString const& name, io::ostream&)>&& logger) {
mName = name;
mLogger = std::move(logger);
return *this;
}
Program& Program::shader(ShaderStage shader, void const* data, size_t size) {
Program& Program::shader(ShaderStage shader, void const* data, size_t const size) {
ShaderBlob blob(size);
std::copy_n((const uint8_t *)data, size, blob.data());
mShadersSource[size_t(shader)] = std::move(blob);
return *this;
}
Program& Program::shaderLanguage(ShaderLanguage shaderLanguage) {
Program& Program::shaderLanguage(ShaderLanguage const shaderLanguage) {
mShaderLanguage = shaderLanguage;
return *this;
}
Program& Program::descriptorBindings(backend::descriptor_set_t set,
Program& Program::descriptorBindings(descriptor_set_t const set,
DescriptorBindingsInfo descriptorBindings) noexcept {
mDescriptorBindings[set] = std::move(descriptorBindings);
return *this;
}
Program& Program::uniforms(uint32_t index, utils::CString name, UniformInfo uniforms) noexcept {
Program& Program::uniforms(uint32_t index, CString name, UniformInfo uniforms) {
mBindingUniformsInfo.reserve(mBindingUniformsInfo.capacity() + 1);
mBindingUniformsInfo.emplace_back(index, std::move(name), std::move(uniforms));
return *this;
@@ -88,17 +88,17 @@ Program& Program::specializationConstants(SpecializationConstantsInfo specConsta
}
Program& Program::pushConstants(ShaderStage stage,
utils::FixedCapacityVector<PushConstant> constants) noexcept {
FixedCapacityVector<PushConstant> constants) noexcept {
mPushConstants[static_cast<uint8_t>(stage)] = std::move(constants);
return *this;
}
Program& Program::cacheId(uint64_t cacheId) noexcept {
Program& Program::cacheId(uint64_t const cacheId) noexcept {
mCacheId = cacheId;
return *this;
}
Program& Program::multiview(bool multiview) noexcept {
Program& Program::multiview(bool const multiview) noexcept {
mMultiview = multiview;
return *this;
}

View File

@@ -52,7 +52,7 @@ PlatformMetal::~PlatformMetal() noexcept {
delete pImpl;
}
Driver* PlatformMetal::createDriver(void* /*sharedContext*/, const Platform::DriverConfig& driverConfig) noexcept {
Driver* PlatformMetal::createDriver(void* /*sharedContext*/, const Platform::DriverConfig& driverConfig) {
pImpl->mDrawableFailureBehavior = driverConfig.metalDisablePanicOnDrawableFailure
? DrawableFailureBehavior::ABORT_FRAME
: DrawableFailureBehavior::PANIC;

View File

@@ -20,7 +20,7 @@
namespace filament::backend {
Driver* PlatformNoop::createDriver(void* sharedGLContext, const Platform::DriverConfig& driverConfig) noexcept {
Driver* PlatformNoop::createDriver(void* sharedGLContext, const Platform::DriverConfig& driverConfig) {
return NoopDriver::create();
}

View File

@@ -31,7 +31,7 @@ public:
protected:
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) override;
};
} // namespace filament

View File

@@ -33,6 +33,7 @@
#include <utils/BitmaskEnum.h>
#include <utils/Log.h>
#include <utils/Logger.h>
#include <utils/Panic.h>
#include <utils/bitset.h>
#include <utils/compiler.h>
@@ -49,7 +50,7 @@
namespace filament::backend {
GLDescriptorSet::GLDescriptorSet(OpenGLContext& gl, DescriptorSetLayoutHandle dslh,
GLDescriptorSetLayout const* layout) noexcept
GLDescriptorSetLayout const* layout)
: descriptors(layout->maxDescriptorBinding + 1),
dslh(std::move(dslh)) {
@@ -156,8 +157,9 @@ void GLDescriptorSet::update(OpenGLContext&,
arg.bo = bo;
arg.offset = uint32_t(offset);
} else {
// API usage error. User asked to update the wrong type of descriptor.
PANIC_PRECONDITION("descriptor %d is not a buffer", +binding);
// User asked to update the wrong type of descriptor. This should never happen
// because we're checking that on the filament side
LOG(ERROR) << "descriptor " << +binding << " is not a buffer";
}
}, descriptors[binding].desc);
}
@@ -214,8 +216,9 @@ void GLDescriptorSet::update(OpenGLContext& gl, HandleAllocatorGL& handleAllocat
arg.params = params;
}
} else {
// API usage error. User asked to update the wrong type of descriptor.
PANIC_PRECONDITION("descriptor %d is not a texture", +binding);
// User asked to update the wrong type of descriptor. This should never happen
// because we're checking that on the filament side
LOG(ERROR) << "descriptor " << +binding << " is not a texture";
}
}, descriptors[binding].desc);
}

View File

@@ -52,7 +52,7 @@ struct GLDescriptorSet : public HwDescriptorSet {
using HwDescriptorSet::HwDescriptorSet;
GLDescriptorSet(OpenGLContext& gl, DescriptorSetLayoutHandle dslh,
GLDescriptorSetLayout const* layout) noexcept;
GLDescriptorSetLayout const* layout);
// update a buffer descriptor in the set
void update(OpenGLContext& gl,

View File

@@ -277,7 +277,7 @@ void OpenGLContext::terminate() noexcept {
}
void OpenGLContext::destroyWithContext(
size_t index, std::function<void(OpenGLContext&)> const& closure) noexcept {
size_t index, std::function<void(OpenGLContext&)> const& closure) {
if (index == 0) {
// Note: we only need to delay the destruction of objects on the unprotected context
// (index 0) because the protected context is always immediately destroyed and all its
@@ -296,7 +296,7 @@ void OpenGLContext::unbindEverything() noexcept {
// worry about.
}
void OpenGLContext::synchronizeStateAndCache(size_t index) noexcept {
void OpenGLContext::synchronizeStateAndCache(size_t index) {
// if we're just switching back to context 0, run all the pending destructors
if (index == 0) {
@@ -865,10 +865,12 @@ GLuint OpenGLContext::bindFramebuffer(GLenum target, GLuint buffer) noexcept {
if (UTILS_UNLIKELY(buffer == 0)) {
// we're binding the default frame buffer, resolve its actual name
auto& defaultFboForThisContext = mDefaultFbo[contextIndex];
if (UTILS_UNLIKELY(!defaultFboForThisContext.has_value())) {
defaultFboForThisContext = GLuint(mPlatform.getDefaultFramebufferObject());
}
buffer = defaultFboForThisContext.value();
// by construction, defaultFboForThisContext has a value. value_or() avoids a throwing call.
buffer = defaultFboForThisContext.value_or(0);
}
bindFramebufferResolved(target, buffer);
return buffer;

View File

@@ -193,7 +193,7 @@ public:
void deleteBuffer(GLuint buffer, GLenum target) noexcept;
void deleteVertexArray(GLuint vao) noexcept;
void destroyWithContext(size_t index, std::function<void(OpenGLContext&)> const& closure) noexcept;
void destroyWithContext(size_t index, std::function<void(OpenGLContext&)> const& closure);
// glGet*() values
struct Gets {
@@ -498,7 +498,7 @@ public:
} procs{};
void unbindEverything() noexcept;
void synchronizeStateAndCache(size_t index) noexcept;
void synchronizeStateAndCache(size_t index);
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
GLuint getSamplerSlow(SamplerParams sp) const noexcept;

View File

@@ -3213,7 +3213,7 @@ void OpenGLDriver::setExternalStream(Handle<HwTexture> th, Handle<HwStream> sh)
}
UTILS_NOINLINE
void OpenGLDriver::attachStream(GLTexture* t, GLStream* hwStream) noexcept {
void OpenGLDriver::attachStream(GLTexture* t, GLStream* hwStream) {
mTexturesWithStreamsAttached.push_back(t);
switch (hwStream->streamType) {
@@ -3799,16 +3799,16 @@ void OpenGLDriver::readBufferSubData(BufferObjectHandle boh,
}
void OpenGLDriver::runEveryNowAndThen(std::function<bool()> fn) noexcept {
void OpenGLDriver::runEveryNowAndThen(std::function<bool()> fn) {
mEveryNowAndThenOps.push_back(std::move(fn));
}
void OpenGLDriver::executeEveryNowAndThenOps() noexcept {
void OpenGLDriver::executeEveryNowAndThenOps() noexcept { // NOLINT(*-exception-escape)
auto& v = mEveryNowAndThenOps;
auto it = v.begin();
while (it != v.end()) {
if ((*it)()) {
it = v.erase(it);
it = v.erase(it); // cannot throw by construction
} else {
++it;
}
@@ -3816,17 +3816,17 @@ void OpenGLDriver::executeEveryNowAndThenOps() noexcept {
}
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
void OpenGLDriver::whenFrameComplete(const std::function<void()>& fn) noexcept {
void OpenGLDriver::whenFrameComplete(const std::function<void()>& fn) {
mFrameCompleteOps.push_back(fn);
}
void OpenGLDriver::whenGpuCommandsComplete(const std::function<void()>& fn) noexcept {
void OpenGLDriver::whenGpuCommandsComplete(const std::function<void()>& fn) {
GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
mGpuCommandCompleteOps.emplace_back(sync, fn);
CHECK_GL_ERROR()
}
void OpenGLDriver::executeGpuCommandsCompleteOps() noexcept {
void OpenGLDriver::executeGpuCommandsCompleteOps() noexcept { // NOLINT(*-exception-escape)
auto& v = mGpuCommandCompleteOps;
auto it = v.begin();
while (it != v.end()) {
@@ -3842,13 +3842,13 @@ void OpenGLDriver::executeGpuCommandsCompleteOps() noexcept {
// ready
it->second();
glDeleteSync(sync);
it = v.erase(it);
it = v.erase(it); // cannot throw by construction
break;
default:
// This should never happen, but is very problematic if it does, as we might leak
// some data depending on what the callback does. However, we clean up our own state.
glDeleteSync(sync);
it = v.erase(it);
it = v.erase(it); // cannot throw by construction
break;
}
}

View File

@@ -395,23 +395,23 @@ private:
std::unordered_map<GLuint, BufferObjectStreamDescriptor> mStreamUniformDescriptors;
void attachStream(GLTexture* t, GLStream* stream) noexcept;
void attachStream(GLTexture* t, GLStream* stream);
void detachStream(GLTexture* t) noexcept;
void replaceStream(GLTexture* t, GLStream* stream) noexcept;
math::mat3f getStreamTransformMatrix(Handle<HwStream> sh);
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
// tasks executed on the main thread after the fence signaled
void whenGpuCommandsComplete(const std::function<void()>& fn) noexcept;
void whenGpuCommandsComplete(const std::function<void()>& fn);
void executeGpuCommandsCompleteOps() noexcept;
std::vector<std::pair<GLsync, std::function<void()>>> mGpuCommandCompleteOps;
void whenFrameComplete(const std::function<void()>& fn) noexcept;
void whenFrameComplete(const std::function<void()>& fn);
std::vector<std::function<void()>> mFrameCompleteOps;
#endif
// tasks regularly executed on the main thread at until they return true
void runEveryNowAndThen(std::function<bool()> fn) noexcept;
void runEveryNowAndThen(std::function<bool()> fn);
void executeEveryNowAndThenOps() noexcept;
std::vector<std::function<bool()>> mEveryNowAndThenOps;

View File

@@ -121,7 +121,7 @@ void OpenGLProgram::initialize(OpenGLDriver& gld) {
* checkProgramStatus() has been successfully called.
*/
void OpenGLProgram::initializeProgramState(OpenGLContext& context, GLuint program,
LazyInitializationData& lazyInitializationData) noexcept {
LazyInitializationData& lazyInitializationData) {
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
// from the pipeline layout we compute a mapping from {set, binding} to {binding}

View File

@@ -106,7 +106,7 @@ private:
void initialize(OpenGLDriver& gld);
void initializeProgramState(OpenGLContext& context, GLuint program,
LazyInitializationData& lazyInitializationData) noexcept;
LazyInitializationData& lazyInitializationData);
BindingMap mBindingMap; // 8 bytes + out-of-line 256 bytes

View File

@@ -51,7 +51,7 @@ class OpenGLDriver;
bool TimerQueryFactory::mGpuTimeSupported = false;
TimerQueryFactoryInterface* TimerQueryFactory::init(
OpenGLPlatform& platform, OpenGLContext& context) noexcept {
OpenGLPlatform& platform, OpenGLContext& context) {
(void)context;
TimerQueryFactoryInterface* impl = nullptr;

View File

@@ -64,7 +64,7 @@ class TimerQueryFactory {
static bool mGpuTimeSupported;
public:
static TimerQueryFactoryInterface* init(
OpenGLPlatform& platform, OpenGLContext& context) noexcept;
OpenGLPlatform& platform, OpenGLContext& context);
static bool isGpuTimeSupported() noexcept {
return mGpuTimeSupported;

View File

@@ -71,7 +71,7 @@ static CString to_string(int const i) { return utils::to_string(i); }
static CString to_string(float const f) { return "float(" + utils::to_string(f) + ")"; }
static void logCompilationError(ShaderStage shaderType, const char* name, GLuint shaderId,
Program::ShaderBlob const& sourceCode) noexcept;
Program::ShaderBlob const& sourceCode);
static void logProgramLinkError(char const* name, GLuint program) noexcept;
static void process_GOOGLE_cpp_style_line_directive(OpenGLContext const& context, char* source,
@@ -79,7 +79,7 @@ static void process_GOOGLE_cpp_style_line_directive(OpenGLContext const& context
static void process_OVR_multiview2(OpenGLContext const& context, int32_t eyeCount, char* source,
size_t len) noexcept;
static std::string_view process_ARB_shading_language_packing(OpenGLContext& context) noexcept;
static std::array<std::string_view, 3> splitShaderSource(std::string_view source) noexcept;
static std::array<std::string_view, 3> splitShaderSource(std::string_view source);
// ------------------------------------------------------------------------------------------------
@@ -312,7 +312,7 @@ ShaderCompilerService::program_token_t ShaderCompilerService::createProgram(
}
void ShaderCompilerService::compileProgram(
program_token_t const& token, Program&& program) noexcept {
program_token_t const& token, Program&& program) {
auto& gl = mDriver.getContext();
CompilerPriorityQueue const priorityQueue = program.getPriorityQueue();
switch (mMode) {
@@ -586,7 +586,7 @@ void ShaderCompilerService::handleCanceledTokensForThreadPool() {
// ------------------------------------------------------------------------------------------------
void ShaderCompilerService::runAtNextTick(CompilerPriorityQueue priority,
program_token_t const& token, Job job) noexcept {
program_token_t const& token, Job job) {
// insert items in order of priority and at the end of the range
auto& ops = mRunAtNextTickOps;
auto const pos = std::lower_bound(ops.begin(), ops.end(), priority,
@@ -614,7 +614,7 @@ bool ShaderCompilerService::cancelTickOp(program_token_t const& token) noexcept
return false;
}
void ShaderCompilerService::executeTickOps() noexcept {
void ShaderCompilerService::executeTickOps() {
auto& ops = mRunAtNextTickOps;
auto it = ops.begin();
while (it != ops.end()) {
@@ -636,7 +636,7 @@ bool ShaderCompilerService::shouldCompileSynchronousProgramThisTick() const noex
mNumTicksUntilNextSynchronousProgram == 0);
}
void ShaderCompilerService::compilePendingSynchronousPrograms() noexcept {
void ShaderCompilerService::compilePendingSynchronousPrograms() {
if (mDriver.getDriverConfig().disableAmortizedShaderCompile) {
return;
}
@@ -655,7 +655,7 @@ void ShaderCompilerService::compilePendingSynchronousPrograms() noexcept {
}
void ShaderCompilerService::compilePendingSynchronousProgramNow(
program_token_t const& token) noexcept {
program_token_t const& token) {
if (mDriver.getDriverConfig().disableAmortizedShaderCompile) {
return;
}
@@ -692,7 +692,7 @@ void ShaderCompilerService::cancelPendingSynchronousProgram(program_token_t cons
/* static */ void ShaderCompilerService::compileShaders(OpenGLContext& context,
Program::ShaderSource shadersSource,
FixedCapacityVector<Program::SpecializationConstant> const& specializationConstants,
bool multiview, program_token_t const& token) noexcept {
bool multiview, program_token_t const& token) {
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
auto const appendSpecConstantString = +[](CString& s, Program::SpecializationConstant const& sc) {
@@ -817,7 +817,7 @@ void ShaderCompilerService::cancelPendingSynchronousProgram(program_token_t cons
return true;
}
/* static */ void ShaderCompilerService::checkCompileStatus(program_token_t const& token) noexcept {
/* static */ void ShaderCompilerService::checkCompileStatus(program_token_t const& token) {
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
UTILS_NOUNROLL
@@ -839,7 +839,7 @@ void ShaderCompilerService::cancelPendingSynchronousProgram(program_token_t cons
}
/* static */ void ShaderCompilerService::linkProgram(OpenGLContext const& context,
program_token_t const& token) noexcept {
program_token_t const& token) {
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
// Shader compilation should be completed by now. Check the status and log errors on failure.
@@ -933,7 +933,7 @@ void ShaderCompilerService::cancelPendingSynchronousProgram(program_token_t cons
UTILS_NOINLINE
/* static */ void logCompilationError(ShaderStage shaderType, const char* name,
GLuint const shaderId,
UTILS_UNUSED_IN_RELEASE Program::ShaderBlob const& sourceCode) noexcept {
UTILS_UNUSED_IN_RELEASE Program::ShaderBlob const& sourceCode) {
// Collects the current GL error for additional context. While often redundant,
// errors like `GL_CONTEXT_LOST` can occur asynchronously after `glCompileShader`.
@@ -1179,7 +1179,7 @@ mediump vec4 unpackSnorm4x8(highp uint v) {
// - the version line
// - extensions
// - everything else
/* static */ std::array<std::string_view, 3> splitShaderSource(std::string_view source) noexcept {
/* static */ std::array<std::string_view, 3> splitShaderSource(std::string_view source) {
auto const version_start = source.find("#version");
assert_invariant(version_start != std::string_view::npos);

View File

@@ -148,16 +148,16 @@ private:
// Methods for SYNCHRONOUS and ASYNCHRONOUS modes.
void runAtNextTick(CompilerPriorityQueue priority, program_token_t const& token,
Job job) noexcept;
void executeTickOps() noexcept;
Job job);
void executeTickOps();
bool cancelTickOp(program_token_t const& token) noexcept;
bool shouldCompileSynchronousProgramThisTick() const noexcept;
void compilePendingSynchronousPrograms() noexcept;
void compilePendingSynchronousProgramNow(program_token_t const& token) noexcept;
void compilePendingSynchronousPrograms();
void compilePendingSynchronousProgramNow(program_token_t const& token);
void cancelPendingSynchronousProgram(program_token_t const& token) noexcept;
void compileProgram(program_token_t const& token, Program&& program) noexcept;
void compileProgram(program_token_t const& token, Program&& program);
// Compile shaders with the given `shaderSource`. `gl.shaders` is always populated with valid
// shader IDs after this method. But this doesn't necessarily mean the shaders are successfully
@@ -165,20 +165,20 @@ private:
static void compileShaders(OpenGLContext& context, Program::ShaderSource shadersSource,
utils::FixedCapacityVector<Program::SpecializationConstant> const&
specializationConstants,
bool multiview, program_token_t const& token) noexcept;
bool multiview, program_token_t const& token);
// Check if the shader compilation is completed. You may want to call this when the extension
// `KHR_parallel_shader_compile` is enabled.
static bool isCompileCompleted(program_token_t const& token) noexcept;
// Check compilation status of the shaders and log errors on failure.
static void checkCompileStatus(program_token_t const& token) noexcept;
static void checkCompileStatus(program_token_t const& token);
// Create a program by linking the compiled shaders. `gl.program` is always populated with a
// valid program ID after this method. But this doesn't necessarily mean the program is
// successfully linked. Errors can be checked by calling `checkLinkStatusAndCleanupShaders`
// later.
static void linkProgram(OpenGLContext const& context, program_token_t const& token) noexcept;
static void linkProgram(OpenGLContext const& context, program_token_t const& token);
// Check if the program link is completed. You may want to call this when the extension
// `KHR_parallel_shader_compile` is enabled.

View File

@@ -148,7 +148,7 @@ PlatformCocoaGL::~PlatformCocoaGL() noexcept {
delete pImpl;
}
Driver* PlatformCocoaGL::createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
Driver* PlatformCocoaGL::createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) {
// NSOpenGLPFAColorSize: when unspecified, a format that matches the screen is preferred
NSOpenGLPixelFormatAttribute pixelFormatAttributes[] = {
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,

View File

@@ -64,7 +64,7 @@ PlatformCocoaTouchGL::~PlatformCocoaTouchGL() noexcept {
delete pImpl;
}
Driver* PlatformCocoaTouchGL::createDriver(void* sharedGLContext, const Platform::DriverConfig& driverConfig) noexcept {
Driver* PlatformCocoaTouchGL::createDriver(void* sharedGLContext, const Platform::DriverConfig& driverConfig) {
EAGLSharegroup* sharegroup = (__bridge EAGLSharegroup*) sharedGLContext;
EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3 sharegroup:sharegroup];

View File

@@ -119,7 +119,7 @@ bool PlatformEGL::isOpenGL() const noexcept {
PlatformEGL::ExternalImageEGL::~ExternalImageEGL() = default;
Driver* PlatformEGL::createDriver(void* sharedContext, const DriverConfig& driverConfig) noexcept {
Driver* PlatformEGL::createDriver(void* sharedContext, const DriverConfig& driverConfig) {
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
assert_invariant(mEGLDisplay != EGL_NO_DISPLAY);
@@ -500,7 +500,7 @@ bool PlatformEGL::isMSAASwapChainSupported(uint32_t samples) const noexcept {
}
Platform::SwapChain* PlatformEGL::createSwapChain(
void* nativeWindow, uint64_t flags) noexcept {
void* nativeWindow, uint64_t flags) {
Config attribs;
@@ -561,7 +561,7 @@ Platform::SwapChain* PlatformEGL::createSwapChain(
}
Platform::SwapChain* PlatformEGL::createSwapChain(
uint32_t width, uint32_t height, uint64_t flags) noexcept {
uint32_t width, uint32_t height, uint64_t flags) {
Config attribs = {
{ EGL_WIDTH, EGLint(width) },

View File

@@ -198,7 +198,7 @@ void backend::PlatformEGLAndroid::preCommit() noexcept {
}
Driver* PlatformEGLAndroid::createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept {
const Platform::DriverConfig& driverConfig) {
// the refresh rate default value doesn't matter, we change it later
int32_t const tid = gettid();

View File

@@ -39,7 +39,7 @@ bool PlatformEGLHeadless::isOpenGL() const noexcept {
}
backend::Driver* PlatformEGLHeadless::createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept {
const Platform::DriverConfig& driverConfig) {
EGLBoolean bindAPI = eglBindAPI(EGL_OPENGL_API);
if (UTILS_UNLIKELY(!bindAPI)) {
LOG(ERROR) << "eglBindAPI EGL_OPENGL_API failed";

View File

@@ -132,7 +132,7 @@ namespace filament::backend {
using namespace backend;
Driver* PlatformGLX::createDriver(void* sharedGLContext,
const DriverConfig& driverConfig) noexcept {
const DriverConfig& driverConfig) {
loadLibraries();
// Get the display device
mGLXDisplay = g_x11.openDisplay(NULL);

View File

@@ -113,7 +113,7 @@ private:
}// anonymous namespace
Driver* PlatformOSMesa::createDriver(void* sharedGLContext,
const DriverConfig& driverConfig) noexcept {
const DriverConfig& driverConfig) {
OSMesaAPI* api = new OSMesaAPI();
mOsMesaApi = api;

View File

@@ -75,7 +75,7 @@ struct WGLSwapChain {
static PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs = nullptr;
Driver* PlatformWGL::createDriver(void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept {
const Platform::DriverConfig& driverConfig) {
int result = 0;
int pixelFormat = 0;
DWORD dwError = 0;

View File

@@ -21,7 +21,7 @@ namespace filament::backend {
using namespace backend;
Driver* PlatformWebGL::createDriver(void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept {
const Platform::DriverConfig& driverConfig) {
return OpenGLPlatform::createDefaultDriver(this, sharedGLContext, driverConfig);
}

View File

@@ -713,7 +713,7 @@ void VulkanPlatform::terminate() {
// This is the main entry point for context creation.
Driver* VulkanPlatform::createDriver(void* sharedContext,
Platform::DriverConfig const& driverConfig) noexcept {
Platform::DriverConfig const& driverConfig) {
// Load Vulkan entry points.
FILAMENT_CHECK_POSTCONDITION(bluevk::initialize()) << "BlueVK is unable to load entry points.";

View File

@@ -694,7 +694,7 @@ wgpu::Device WebGPUPlatform::requestDevice(wgpu::Adapter const& adapter) {
}
Driver* WebGPUPlatform::createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept {
const Platform::DriverConfig& driverConfig) {
if (sharedContext) {
FWGPU_LOGW << "sharedContext is ignored/unused in the WebGPU backend. A non-null "
"sharedContext was provided, but it will be ignored.";

View File

@@ -107,18 +107,19 @@ void FrameInfoManager::beginFrame(DriverApi& driver, Config const& config, uint3
// read the pending timer queries until we find one that's not ready
}
#if 0
// keep this just for debugging
if constexpr (false) {
using namespace utils;
auto h = getFrameInfoHistory(1);
if (!h.empty()) {
DLOG(INFO) << frameId << ": " << h[0].frameId << " (" << frameId - h[0].frameId << ")"
<< ", Dm=" << h[0].endFrame - h[0].beginFrame
<< ", L =" << h[0].backendBeginFrame - h[0].beginFrame
<< ", Db=" << h[0].backendEndFrame - h[0].backendBeginFrame
<< ", T =" << h[0].frameTime;
}
using namespace utils;
auto h = getFrameInfoHistory(1); // this can throw
if (!h.empty()) {
DLOG(INFO) << frameId << ": " << h[0].frameId << " (" << frameId - h[0].frameId <<
")"
<< ", Dm=" << h[0].endFrame - h[0].beginFrame
<< ", L =" << h[0].backendBeginFrame - h[0].beginFrame
<< ", Db=" << h[0].backendEndFrame - h[0].backendBeginFrame
<< ", T =" << h[0].frameTime;
}
#endif
}
void FrameInfoManager::endFrame(DriverApi& driver) noexcept {
@@ -172,7 +173,7 @@ void FrameInfoManager::denoiseFrameTime(FrameHistoryQueue& history, Config const
}
FixedCapacityVector<Renderer::FrameInfo> FrameInfoManager::getFrameInfoHistory(
size_t historySize) const noexcept {
size_t historySize) const {
auto result = FixedCapacityVector<Renderer::FrameInfo>::with_capacity(MAX_FRAMETIME_HISTORY);
auto const& history = mFrameTimeHistory;
size_t i = 0;
@@ -188,6 +189,7 @@ FixedCapacityVector<Renderer::FrameInfo> FrameInfoManager::getFrameInfoHistory(
for (; i < c && historySize; ++i, --historySize) {
auto const& entry = history[i];
using namespace std::chrono;
// can't throw by construction
result.push_back({
entry.frameId,
duration_cast<nanoseconds>(entry.frameTime).count(),

View File

@@ -123,11 +123,11 @@ public:
return *this;
}
size_t capacity() const {
size_t capacity() const noexcept {
return CAPACITY;
}
size_t size() const {
size_t size() const noexcept {
return mSize;
}
@@ -190,7 +190,7 @@ private:
Storage mStorage[CAPACITY];
uint32_t mFront = 0;
uint32_t mSize = 0;
[[nodiscard]] inline uint32_t advance(uint32_t const v) noexcept {
[[nodiscard]] uint32_t advance(uint32_t const v) noexcept {
return (v + 1) % CAPACITY;
}
};
@@ -223,7 +223,7 @@ public:
return pFront ? *pFront : details::FrameInfo{};
}
utils::FixedCapacityVector<Renderer::FrameInfo> getFrameInfoHistory(size_t historySize) const noexcept;
utils::FixedCapacityVector<Renderer::FrameInfo> getFrameInfoHistory(size_t historySize) const;
private:
using FrameHistoryQueue = CircularQueue<FrameInfoImpl, MAX_FRAMETIME_HISTORY>;
@@ -232,11 +232,11 @@ private:
backend::Handle<backend::HwTimerQuery> handle{};
FrameInfoImpl* pInfo = nullptr;
};
std::array<Query, POOL_COUNT> mQueries;
std::array<Query, POOL_COUNT> mQueries{};
uint32_t mIndex = 0; // index of current query
uint32_t mLast = 0; // index of oldest query still active
FrameInfoImpl* pFront = nullptr; // the most recent slot with a valid frame time
FrameHistoryQueue mFrameTimeHistory;
FrameHistoryQueue mFrameTimeHistory{};
};