Skip to content

backend: Propagate backend thread exceptions to the main thread.#9903

Merged
pixelflinger merged 4 commits into
mainfrom
ma/error-handling
Apr 22, 2026
Merged

backend: Propagate backend thread exceptions to the main thread.#9903
pixelflinger merged 4 commits into
mainfrom
ma/error-handling

Conversation

@pixelflinger
Copy link
Copy Markdown
Collaborator

Introduce a mechanism to catch exceptions thrown on the backend thread and
rethrow them on the main thread. This prevents deadlocks and allows the
application to handle fatal backend failures gracefully.

BUGS=[407545700]
Fixes #8197, #3135

@pixelflinger pixelflinger added the internal Issue/PR does not affect clients label Apr 15, 2026
Base automatically changed from ma/shared-condition to main April 16, 2026 18:30
Comment thread filament/src/details/Fence.h Outdated
Comment thread filament/src/details/Engine.cpp Outdated
Comment thread filament/backend/include/private/backend/CommandBufferQueue.h
Comment thread filament/backend/src/CommandBufferQueue.cpp Outdated
Copy link
Copy Markdown
Contributor

@poweifeng poweifeng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm with nits and a question

Comment thread filament/src/details/MaterialInstance.cpp
Comment thread libs/filamentapp/src/FilamentApp.cpp
Copy link
Copy Markdown
Member

@bejado bejado left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The noexcept must be removed from MetalDriver::execute in order for Metal driver exceptions to be caught.

Comment thread filament/src/details/Engine.h
@pixelflinger pixelflinger force-pushed the ma/error-handling branch 2 times, most recently from 6d2773e to 03038c2 Compare April 17, 2026 23:48
Copy link
Copy Markdown
Contributor

@z3moon z3moon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM except for minor issues.

Comment thread android/filament-android/src/main/cpp/Engine.cpp Outdated
Comment thread android/filament-android/src/main/cpp/Engine.cpp Outdated
Comment thread android/filament-android/src/main/cpp/Engine.cpp Outdated
Comment thread android/common/JniUtils.h Outdated
- Replaced assert_invariant with FILAMENT_CHECK_PRECONDITION in
  Renderer::beginFrame for caller bugs.
- Removed noexcept from Camera::setCustomProjection to allow precondition
  checks to throw.
- Removed noexcept from Texture and InstanceBuffer methods using precondition
  checks.
- Documented silent clamping in View::setBloomOptions.
- Clarified comment in FrameGraphResources regarding preconditions.
- Refined MaterialInstance::commit to split texture loop into check and update
  passes, preventing partial state changes on precondition failure.
Introduce a mechanism to catch exceptions thrown on the backend thread and
rethrow them on the main thread. This prevents deadlocks and allows the
application to handle fatal backend failures gracefully.

- Consolidate synchronization primitives in DriverBase.
- Add mHasUnrecoverableError flag to interrupt blocked fence waits.
- Optimize waitForFence to avoid extra atomic reads in common paths.
- Propagate FenceStatus::ERROR across all backends.
- CommandBufferQueue now stores a std::exception_ptr when the backend fails.
- The backend enters a "zombie" state on failure, skipping further command
  execution but allowing clean shutdown.
- Public APIs in Renderer and Engine now check for stored exceptions and
  rethrow them, documented with @throws.
- Guarded by __EXCEPTIONS to ensure no overhead when exceptions are disabled.
- Add unit test for fence interruption and document new APIs.

BUGS=[407545700]
- Update Renderer::beginFrame() and Renderer::shouldRenderFrame() to
  return false early if an unrecoverable backend exception has been
  delivered to the main thread.
- Document the new return behavior for beginFrame() and
  shouldRenderFrame() in Renderer.h.
- Add Engine::hasUnrecoverableFailure() to the public API to allow
  apps to check for fatal errors without relying on exceptions.
- Implement hasUnrecoverableFailure() in FEngine by delegating to
  CommandBufferQueue.
- Expose Engine::hasUnrecoverableFailure() to Java bindings
  (Engine.java and JNI).
- Expose Engine::hasUnrecoverableFailure() to JavaScript bindings
  (jsbindings.cpp).
@pixelflinger pixelflinger merged commit f4a079f into main Apr 22, 2026
18 checks passed
@pixelflinger pixelflinger deleted the ma/error-handling branch April 22, 2026 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal Issue/PR does not affect clients

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Filament panics unrecoverably in background threads for potentially recoverable issues

4 participants