diff --git a/filament/backend/include/private/backend/HandleAllocator.h b/filament/backend/include/private/backend/HandleAllocator.h index 9a7c575ee7..f4abde8610 100644 --- a/filament/backend/include/private/backend/HandleAllocator.h +++ b/filament/backend/include/private/backend/HandleAllocator.h @@ -51,11 +51,11 @@ public: * struct ConcreteTexture : public HwTexture { * ConcreteTexture(int w, int h); * }; - * Handle h = allocate(w, h); + * Handle h = allocateAndConstruct(w, h); * */ template - Handle allocate(ARGS&& ... args) noexcept { + Handle allocateAndConstruct(ARGS&& ... args) noexcept { Handle h{ allocateHandle(sizeof(D)) }; D* addr = handle_cast(h); new(addr) D(std::forward(args)...); @@ -67,9 +67,59 @@ public: return h; } + /* + * Allocates (without constructing) a D object and returns a Handle + * + * e.g.: + * struct ConcreteTexture : public HwTexture { + * ConcreteTexture(int w, int h); + * }; + * Handle h = allocate(); + * + */ + template + Handle allocate() noexcept { + Handle h{ allocateHandle(sizeof(D)) }; +#if HANDLE_TYPE_SAFETY + D* addr = handle_cast(h); + mLock.lock(); + mHandleTypeId[addr] = typeid(D).name(); + mLock.unlock(); +#endif + return h; + } + + /* * Destroys the object D at Handle and construct a new D in its place * e.g.: + * Handle h = allocateAndConstruct(w, h); + * ConcreteTexture* p = reconstruct(h, w, h); + */ + template + typename std::enable_if_t, D>* + destroyAndConstruct(Handle const& handle, ARGS&& ... args) noexcept { + assert_invariant(handle); + D* addr = handle_cast(const_cast&>(handle)); + assert_invariant(addr); + + // currently we implement construct<> with dtor+ctor, we could use operator= also + // but all our dtors are trivial, ~D() is actually a noop. + addr->~D(); + new(addr) D(std::forward(args)...); + +#if HANDLE_TYPE_SAFETY + mLock.lock(); + mHandleTypeId[addr] = typeid(D).name(); + mLock.unlock(); +#endif + return addr; + } + + /* + * Construct a new D at Handle + * e.g.: + * Handle h = allocate(); * ConcreteTexture* p = construct(h, w, h); */ template @@ -78,10 +128,6 @@ public: assert_invariant(handle); D* addr = handle_cast(const_cast&>(handle)); assert_invariant(addr); - - // currently we implement construct<> with dtor+ctor, we could use operator= also - // but all our dtors are trivial, ~D() is actually a noop. - addr->~D(); new(addr) D(std::forward(args)...); #if HANDLE_TYPE_SAFETY diff --git a/filament/backend/src/opengl/OpenGLDriver.cpp b/filament/backend/src/opengl/OpenGLDriver.cpp index ba079c856d..9cb1f2bd64 100644 --- a/filament/backend/src/opengl/OpenGLDriver.cpp +++ b/filament/backend/src/opengl/OpenGLDriver.cpp @@ -1471,7 +1471,7 @@ FenceStatus OpenGLDriver::wait(Handle fh, uint64_t timeout) { // we can end-up here if: // - the platform doesn't support h/w fences // - wait() was called before the fence was asynchronously created. - // This case is not handled in OpenGLDriver but is handle by FFence. + // This case is not handled in OpenGLDriver but is handled by FFence. // TODO: move FFence logic into the backend. return FenceStatus::ERROR; } diff --git a/filament/backend/src/opengl/OpenGLDriver.h b/filament/backend/src/opengl/OpenGLDriver.h index 20659242d7..00afd9ea75 100644 --- a/filament/backend/src/opengl/OpenGLDriver.h +++ b/filament/backend/src/opengl/OpenGLDriver.h @@ -253,13 +253,13 @@ private: template backend::Handle initHandle(ARGS&& ... args) noexcept { - return mHandleAllocator.allocate(std::forward(args) ...); + return mHandleAllocator.allocateAndConstruct(std::forward(args) ...); } template typename std::enable_if::value, D>::type* construct(backend::Handle const& handle, ARGS&& ... args) noexcept { - return mHandleAllocator.construct(handle, std::forward(args) ...); + return mHandleAllocator.destroyAndConstruct(handle, std::forward(args) ...); } template