diff --git a/filament/backend/include/private/backend/HandleAllocator.h b/filament/backend/include/private/backend/HandleAllocator.h index afc6dc924e..d083fe3da9 100644 --- a/filament/backend/include/private/backend/HandleAllocator.h +++ b/filament/backend/include/private/backend/HandleAllocator.h @@ -181,6 +181,18 @@ public: return static_cast(p); } + template + bool is_valid(Handle& handle) { + if (handle && isPoolHandle(handle.getId())) { + auto [p, tag] = handleToPointer(handle.getId()); + uint8_t const age = (tag & HANDLE_AGE_MASK) >> HANDLE_AGE_SHIFT; + auto const pNode = static_cast(p); + uint8_t const expectedAge = pNode[-1].age; + return expectedAge == age; + } + return true; + } + template inline typename std::enable_if_t< std::is_pointer_v && diff --git a/filament/backend/src/opengl/OpenGLDriver.cpp b/filament/backend/src/opengl/OpenGLDriver.cpp index 4f88c9717f..5b011ee625 100644 --- a/filament/backend/src/opengl/OpenGLDriver.cpp +++ b/filament/backend/src/opengl/OpenGLDriver.cpp @@ -2336,9 +2336,9 @@ void OpenGLDriver::updateSamplerGroup(Handle sbh, auto const* const pSamplers = (SamplerDescriptor const*)data.buffer; for (size_t i = 0, c = sb->textureUnitEntries.size(); i < c; i++) { GLuint samplerId = 0u; - const GLTexture* t = nullptr; - if (UTILS_LIKELY(pSamplers[i].t)) { - t = handle_cast(pSamplers[i].t); + Handle th = pSamplers[i].t; + if (UTILS_LIKELY(th)) { + GLTexture const* const t = handle_cast(th); assert_invariant(t); SamplerParams params = pSamplers[i].s; @@ -2394,7 +2394,7 @@ void OpenGLDriver::updateSamplerGroup(Handle sbh, // which is not an error. } - sb->textureUnitEntries[i] = { t, samplerId }; + sb->textureUnitEntries[i] = { th, samplerId }; } scheduleDestroy(std::move(data)); } diff --git a/filament/backend/src/opengl/OpenGLDriver.h b/filament/backend/src/opengl/OpenGLDriver.h index d5e1b797b6..5345d474bf 100644 --- a/filament/backend/src/opengl/OpenGLDriver.h +++ b/filament/backend/src/opengl/OpenGLDriver.h @@ -126,7 +126,7 @@ public: struct GLSamplerGroup : public HwSamplerGroup { using HwSamplerGroup::HwSamplerGroup; struct Entry { - GLTexture const* texture = nullptr; + Handle th; GLuint sampler = 0u; }; utils::FixedCapacityVector textureUnitEntries; @@ -256,6 +256,11 @@ private: return mHandleAllocator.handle_cast(handle); } + template + bool is_valid(Handle& handle) { + return mHandleAllocator.is_valid(handle); + } + template inline typename std::enable_if_t< std::is_pointer_v && diff --git a/filament/backend/src/opengl/OpenGLProgram.cpp b/filament/backend/src/opengl/OpenGLProgram.cpp index 6c5eab9a44..7a85e3c63c 100644 --- a/filament/backend/src/opengl/OpenGLProgram.cpp +++ b/filament/backend/src/opengl/OpenGLProgram.cpp @@ -20,21 +20,24 @@ #include "OpenGLDriver.h" #include "ShaderCompilerService.h" +#include #include +#include -#include - -#include #include +#include +#include #include #include +#include #include #include #include #include #include +#include namespace filament::backend { @@ -241,8 +244,9 @@ void OpenGLProgram::updateSamplers(OpenGLDriver* const gld) const noexcept { assert_invariant(sb); if (!sb) continue; // should never happen, this would be a user error. for (uint8_t j = 0, m = sb->textureUnitEntries.size(); j < m; ++j, ++tmu) { // "<=" on purpose here - const GLTexture* const t = sb->textureUnitEntries[j].texture; - if (t) { // program may not use all samplers of sampler group + Handle th = sb->textureUnitEntries[j].th; + if (th) { // program may not use all samplers of sampler group + GLTexture const* const t = gld->handle_cast(th); gld->bindTexture(tmu, t); #ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2 if (UTILS_LIKELY(!es2)) {