Skip to content

Commit 3f4dac6

Browse files
authored
Fix a crash for IBL resource loading (#8001)
This fixes a crash introduced by a8ace28 The refactored FrameInfoManager can cause a crash when IBL resource loading happens because now the getLastFrameInfo() references an invalid value via the `front` method. Return the default FrameInfo to resolve this. Also fix a null pointer reference bug for OpenGLTimer::State, which happenes when the renderer for IBLPrefilterContext is destroyed.
1 parent 40ae416 commit 3f4dac6

File tree

2 files changed

+21
-17
lines changed

2 files changed

+21
-17
lines changed

filament/backend/src/opengl/OpenGLTimerQuery.cpp

+18-14
Original file line numberDiff line numberDiff line change
@@ -143,21 +143,25 @@ void TimerQueryNativeFactory::endTimeElapsedQuery(OpenGLDriver& driver, GLTimerQ
143143

144144
driver.runEveryNowAndThen([&context = mContext, weak]() -> bool {
145145
auto state = weak.lock();
146-
if (state) {
147-
GLuint available = 0;
148-
context.procs.getQueryObjectuiv(state->gl.query, GL_QUERY_RESULT_AVAILABLE, &available);
149-
CHECK_GL_ERROR(utils::slog.e)
150-
if (!available) {
151-
// we need to try this one again later
152-
return false;
153-
}
154-
GLuint64 elapsedTime = 0;
155-
// we won't end-up here if we're on ES and don't have GL_EXT_disjoint_timer_query
156-
context.procs.getQueryObjectui64v(state->gl.query, GL_QUERY_RESULT, &elapsedTime);
157-
state->elapsed.store((int64_t)elapsedTime, std::memory_order_relaxed);
158-
} else {
159-
state->elapsed.store(int64_t(TimerQueryResult::ERROR), std::memory_order_relaxed);
146+
if (!state) {
147+
// The timer query state has been destroyed on the way, very likely due to the IBL
148+
// prefilter context destruction. We still return true to get this element removed from
149+
// the query list.
150+
return true;
160151
}
152+
153+
GLuint available = 0;
154+
context.procs.getQueryObjectuiv(state->gl.query, GL_QUERY_RESULT_AVAILABLE, &available);
155+
CHECK_GL_ERROR(utils::slog.e)
156+
if (!available) {
157+
// we need to try this one again later
158+
return false;
159+
}
160+
GLuint64 elapsedTime = 0;
161+
// we won't end-up here if we're on ES and don't have GL_EXT_disjoint_timer_query
162+
context.procs.getQueryObjectui64v(state->gl.query, GL_QUERY_RESULT, &elapsedTime);
163+
state->elapsed.store((int64_t)elapsedTime, std::memory_order_relaxed);
164+
161165
return true;
162166
});
163167
}

filament/src/FrameInfo.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,9 @@ class FrameInfoManager {
163163
// call this immediately before "swap buffers"
164164
void endFrame(backend::DriverApi& driver) noexcept;
165165

166-
details::FrameInfo const& getLastFrameInfo() const noexcept {
167-
// if pFront is not set yet, return front() but in this case front().valid will be false
168-
return pFront ? *pFront : mFrameTimeHistory.front();
166+
details::FrameInfo getLastFrameInfo() const noexcept {
167+
// if pFront is not set yet, return FrameInfo(). But the `valid` field will be false in this case.
168+
return pFront ? *pFront : details::FrameInfo{};
169169
}
170170

171171
utils::FixedCapacityVector<Renderer::FrameInfo> getFrameInfoHistory(size_t historySize) const noexcept;

0 commit comments

Comments
 (0)