From 59593830e5c40c3ee8a98bfe7a45a2b4e0b4e66a Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 6 Aug 2024 21:54:32 -0700 Subject: [PATCH] Fix skipFrame incorrectly asserts in some cases BUGS=[357992376] --- filament/src/details/Renderer.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/filament/src/details/Renderer.cpp b/filament/src/details/Renderer.cpp index a756c0cb9c..1b8ffdd359 100644 --- a/filament/src/details/Renderer.cpp +++ b/filament/src/details/Renderer.cpp @@ -344,10 +344,14 @@ bool FRenderer::beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeN * to ignore the return value and render the frame anyway -- which is perfectly fine. * The remaining work will be done when the first render() call is made. */ - auto beginFrameInternal = [this, appVsync]() { + auto beginFrameInternal = [this, appVsync, swapChain]() { FEngine& engine = mEngine; FEngine::DriverApi& driver = engine.getDriverApi(); + // we need to re-set mSwapChain here because if a frame was marked as "skip" but the + // user ignored us, we'd still want mSwapChain to be set. + mSwapChain = swapChain; + driver.beginFrame( appVsync.time_since_epoch().count(), mDisplayInfo.refreshRate == 0.0 ? 0 : int64_t( @@ -376,6 +380,10 @@ bool FRenderer::beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeN // so we need to delay this work until that happens. mBeginFrameInternal = beginFrameInternal; + // clear mSwapChain because the frame should be skipped (it will be re-set if the user + // ignores the skip) + mSwapChain = nullptr; + // we need to flush in this case, to make sure the tick() call is executed at some point engine.flush(); @@ -534,8 +542,6 @@ void FRenderer::renderStandaloneView(FView const* view) { void FRenderer::render(FView const* view) { SYSTRACE_CALL(); - assert_invariant(mSwapChain); - if (UTILS_UNLIKELY(mBeginFrameInternal)) { // this should not happen, the user should not call render() if we returned false from // beginFrame(). But because this is allowed, we handle it gracefully. @@ -543,6 +549,9 @@ void FRenderer::render(FView const* view) { mBeginFrameInternal = {}; } + // after beginFrame() is called, mSwapChain should be true + assert_invariant(mSwapChain); + if (UTILS_LIKELY(view && view->getScene() && view->hasCamera())) { if (mViewRenderedCount) { // This is a good place to kick the GPU, since we've rendered a View before,