From b540909f188cf02faac79075bae23e1b11af0d90 Mon Sep 17 00:00:00 2001 From: Haroon Qureshi Date: Fri, 15 May 2026 10:43:16 -0700 Subject: [PATCH] Ensure swap chains are resized appropriately. The swap chain dimensions are a union of all render request viewport sizes that use the swap chain. PiperOrigin-RevId: 916078573 Change-Id: If26a9e1486006ed346227120a361773bfa23f292 --- .../filament/filament/filament_context.cc | 71 ++++++++++++++----- .../filament/filament/filament_context.h | 3 +- 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/src/experimental/filament/filament/filament_context.cc b/src/experimental/filament/filament/filament_context.cc index fdee15c2..e381d402 100644 --- a/src/experimental/filament/filament/filament_context.cc +++ b/src/experimental/filament/filament/filament_context.cc @@ -14,6 +14,7 @@ #include "experimental/filament/filament/filament_context.h" +#include #include #include #include @@ -86,6 +87,13 @@ mjrFrameHandle FilamentContext::Render( mju_error("Only one read request is supported for now."); } + if constexpr (UTILS_HAS_THREADING) { + // Wait until previous frame is completed before requesting a new frame. + engine_->flushAndWait(); + } + + ValidateSwapChains(requests); + bool render_began = false; mjrRenderTarget* current_target = nullptr; for (const mjrRenderRequest& request : requests) { @@ -100,22 +108,6 @@ mjrFrameHandle FilamentContext::Render( mju_error("Cannot read pixels from the window."); } - if constexpr (UTILS_HAS_THREADING) { - // Wait until previous frame is completed before requesting a new frame. - engine_->flushAndWait(); - } - - // If the window size has changed, we need to reacquire the swap chain. - if (request.viewport.width != window_width_ || - request.viewport.height != window_height_) { - if (window_width_ != 0 && window_height_ != 0) { - engine_->destroy(window_swap_chain_); - window_swap_chain_ = engine_->createSwapChain(config_.native_window); - } - window_width_ = request.viewport.width; - window_height_ = request.viewport.height; - } - if (!render_began) { render_began = renderer_->beginFrame(window_swap_chain_); } @@ -196,4 +188,51 @@ void FilamentContext::GetFrameStats(mjrFrameHandle frame, } } +void FilamentContext::ValidateSwapChains( + std::span requests) { + // Determine the maximum extents of the requests. + int max_window_width = 0; + int max_window_height = 0; + int max_offscreen_width = 0; + int max_offscreen_height = 0; + + for (const mjrRenderRequest& request : requests) { + const int width = request.viewport.width + request.viewport.left; + const int height = request.viewport.height + request.viewport.bottom; + if (request.target == nullptr) { + max_window_width = std::max(max_window_width, width); + max_window_height = std::max(max_window_height, height); + } else { + max_offscreen_width = std::max(max_offscreen_width, width); + max_offscreen_height = std::max(max_offscreen_height, height); + } + } + + if (max_window_width && max_window_height) { + if (max_window_width != window_width_ || + max_window_width != window_height_) { + engine_->destroy(window_swap_chain_); + window_width_ = max_window_width; + window_height_ = max_window_height; + if (config_.native_window) { + window_swap_chain_ = engine_->createSwapChain(config_.native_window); + } else { + window_swap_chain_ = + engine_->createSwapChain(window_width_, window_height_); + } + } + } + + if (max_offscreen_width && max_offscreen_height) { + if (max_offscreen_width != config_.width || + max_offscreen_height != config_.height) { + engine_->destroy(offscreen_swap_chain_); + config_.width = max_offscreen_width; + config_.height = max_offscreen_height; + offscreen_swap_chain_ = + engine_->createSwapChain(config_.width, config_.height); + } + } +} + } // namespace mujoco diff --git a/src/experimental/filament/filament/filament_context.h b/src/experimental/filament/filament/filament_context.h index d1b175ce..d1dfbf43 100644 --- a/src/experimental/filament/filament/filament_context.h +++ b/src/experimental/filament/filament/filament_context.h @@ -68,8 +68,9 @@ class FilamentContext : public mjrfContext { } private: - mjrFilamentConfig config_; + void ValidateSwapChains(std::span render_requests); + mjrFilamentConfig config_; filament::Engine* engine_ = nullptr; filament::Renderer* renderer_ = nullptr; filament::SwapChain* window_swap_chain_ = nullptr;