diff --git a/src/experimental/filament/CMakeLists.txt b/src/experimental/filament/CMakeLists.txt index 79e771f9..5c9242aa 100644 --- a/src/experimental/filament/CMakeLists.txt +++ b/src/experimental/filament/CMakeLists.txt @@ -33,6 +33,8 @@ target_sources(${MUJOCO_FILAMENT_TARGET_NAME} filament/drawable.h filament/filament_context.cc filament/filament_context.h + filament/filament_platform_factory.cc + filament/filament_platform_factory.h filament/geom_util.cc filament/geom_util.h filament/gui_view.cc diff --git a/src/experimental/filament/filament/filament_context.cc b/src/experimental/filament/filament/filament_context.cc index 1df934e5..a394560f 100644 --- a/src/experimental/filament/filament/filament_context.cc +++ b/src/experimental/filament/filament/filament_context.cc @@ -38,6 +38,7 @@ #include #include #include +#include "experimental/filament/filament/filament_platform_factory.h" #include "experimental/filament/filament/gui_view.h" #include "experimental/filament/filament/imgui_editor.h" #include "experimental/filament/filament/object_manager.h" @@ -51,31 +52,20 @@ namespace mujoco { FilamentContext::FilamentContext(const mjrFilamentConfig* config, const mjModel* model, mjrContext* con) : config_(*config), context_(con), model_(model) { -#if defined( __EMSCRIPTEN__) - filament::Engine::Backend backend = filament::Engine::Backend::OPENGL; -#else - filament::Engine::Backend backend = filament::Engine::Backend::VULKAN; -#endif + FilamentPlatformSetup setup = CreateFilamentPlatform(config_); + platform_ = std::move(setup.platform); - switch (config_.graphics_api) { - case mjGFX_DEFAULT: - // Use the default based on the platform above. - break; - case mjGFX_OPENGL: - backend = filament::Engine::Backend::OPENGL; - break; - case mjGFX_VULKAN: - backend = filament::Engine::Backend::VULKAN; - break; - default: - mju_error("Unsupported graphics API: %d", config_.graphics_api); - } + filament::Engine::Builder engine_builder; + engine_builder.backend(setup.backend); + engine_builder.platform(platform_.get()); + engine_builder.feature("backend.disable_parallel_shader_compile", + setup.disable_parallel_shader_compile); + engine_ = engine_builder.build(); + + renderer_ = engine_->createRenderer(); const int width = model_->vis.global.offwidth; const int height = model_->vis.global.offheight; - - engine_ = filament::Engine::create(backend); - renderer_ = engine_->createRenderer(); #ifdef __EMSCRIPTEN__ window_swap_chain_ = engine_->createSwapChain(nullptr); #else diff --git a/src/experimental/filament/filament/filament_context.h b/src/experimental/filament/filament/filament_context.h index 230be2ab..483988ba 100644 --- a/src/experimental/filament/filament/filament_context.h +++ b/src/experimental/filament/filament/filament_context.h @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -73,10 +74,13 @@ class FilamentContext { mjrFilamentConfig config_; mjrContext* context_ = nullptr; const mjModel* model_ = nullptr; + filament::Engine* engine_ = nullptr; + filament::Renderer* renderer_ = nullptr; filament::SwapChain* window_swap_chain_ = nullptr; filament::SwapChain* offscreen_swap_chain_ = nullptr; - filament::Renderer* renderer_ = nullptr; + std::unique_ptr platform_; + SceneView::DrawMode last_render_mode_ = SceneView::DrawMode::kNormal; SwapChainType scene_swap_chain_target_ = kWindowSwapChain; SwapChainType gui_swap_chain_target_ = kWindowSwapChain; diff --git a/src/experimental/filament/filament/filament_platform_factory.cc b/src/experimental/filament/filament/filament_platform_factory.cc new file mode 100644 index 00000000..38397380 --- /dev/null +++ b/src/experimental/filament/filament/filament_platform_factory.cc @@ -0,0 +1,78 @@ +// Copyright 2026 DeepMind Technologies Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "experimental/filament/filament/filament_platform_factory.h" + +#include + +#include + +#ifdef __linux__ +#include +#include // IWYU pragma: keep +#include +#include +#include "third_party/filament/libs/bluegl/include/bluegl/BlueGL.h" +#endif + +#include +#include +#include "experimental/filament/render_context_filament.h" + +namespace mujoco { + +static filament::Engine::Backend ResolveBackend(int graphics_api) { +#if defined(__EMSCRIPTEN__) + filament::Engine::Backend backend = filament::Engine::Backend::OPENGL; +#else + filament::Engine::Backend backend = filament::Engine::Backend::VULKAN; +#endif + + switch (graphics_api) { + case mjGFX_DEFAULT: + // Use the default based on the platform above. + break; + case mjGFX_OPENGL: + backend = filament::Engine::Backend::OPENGL; + break; + case mjGFX_VULKAN: + backend = filament::Engine::Backend::VULKAN; + break; + default: + mju_error("Unsupported graphics API: %d", graphics_api); + } + return backend; +} + +FilamentPlatformSetup CreateFilamentPlatform(const mjrFilamentConfig& config) { + FilamentPlatformSetup setup; + setup.backend = ResolveBackend(config.graphics_api); + +#ifdef __linux__ + if (setup.backend == filament::Engine::Backend::OPENGL) { + if (config.native_window == nullptr) { + setup.platform = std::make_unique(); + setup.disable_parallel_shader_compile = true; + } else { + setup.platform = std::make_unique(); + } + } else { + setup.platform = std::make_unique(); + } +#endif + return setup; +} + + +} // namespace mujoco diff --git a/src/experimental/filament/filament/filament_platform_factory.h b/src/experimental/filament/filament/filament_platform_factory.h new file mode 100644 index 00000000..d2a11a60 --- /dev/null +++ b/src/experimental/filament/filament/filament_platform_factory.h @@ -0,0 +1,45 @@ +// Copyright 2026 DeepMind Technologies Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_FILAMENT_PLATFORM_FACTORY_H_ +#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_FILAMENT_PLATFORM_FACTORY_H_ + +#include + +#include "experimental/filament/render_context_filament.h" +#include +#include + +namespace mujoco { + +struct FilamentPlatformSetup { + // The filament::Platform to use for the engine. May be null, in which case + // the engine will be created with a default platform. + std::unique_ptr platform = nullptr; + + // The filament::Engine::Backend to use for the engine. + filament::Engine::Backend backend; + + // Whether to disable parallel shader compilation. + bool disable_parallel_shader_compile = false; +}; + +// Creates a filament::Platform based on the given config and defines the +// filament::Engine::Backend to use. Also returns additional information for +// setting up the filament::Engine for use with the provided Platform. +FilamentPlatformSetup CreateFilamentPlatform(const mjrFilamentConfig& config); + +} // namespace mujoco + +#endif // MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_FILAMENT_PLATFORM_FACTORY_H_