Remove unused material instances before rendering frame.

Also ensure material texture hashes are unique so that the material
cleanup works correctly.

PiperOrigin-RevId: 937206048
Change-Id: Ibed53457ee271f4faae3bcac5fb479b5ce9fc352
This commit is contained in:
Haroon Qureshi
2026-06-24 02:46:04 -07:00
committed by Copybara-Service
parent 29b49991a2
commit 3e33f93ddc
5 changed files with 32 additions and 8 deletions
+3 -3
View File
@@ -94,16 +94,17 @@ mjrfFrameHandle FilamentContext::Render(
ValidateSwapChains(requests);
material_manager_->BeginFrame();
std::unordered_map<mjrfScene*, std::vector<const mjrfRenderRequest*>>
scene_to_requests;
for (const mjrfRenderRequest& request : requests) {
scene_to_requests[request.scene].push_back(&request);
}
material_manager_->PrepareToRender();
for (auto& [scene, requests] : scene_to_requests) {
SceneView::downcast(scene)->PrepareToRender(requests);
}
material_manager_->RemoveUnusedMaterials();
bool render_began = false;
mjrfRenderTarget* current_target = nullptr;
@@ -159,7 +160,6 @@ mjrfFrameHandle FilamentContext::Render(
if (render_began) {
renderer_->endFrame();
material_manager_->EndFrame();
}
if constexpr (!UTILS_HAS_THREADING) {
engine_->execute();
+18 -2
View File
@@ -38,6 +38,13 @@ static void Combine(uint64_t& seed, const T* v) {
seed ^= std::hash<T>()(*v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
static void Combine(uint64_t& seed, const mjrfTexture* texture) {
if (texture) {
const uint64_t id = Texture::downcast(texture)->Id();
Combine(seed, &id);
}
}
template <typename T>
static uint64_t hash(const T& obj) {
static_assert(std::is_trivially_copyable_v<T>,
@@ -77,9 +84,9 @@ MaterialManager::~MaterialManager() {
}
}
void MaterialManager::BeginFrame() { used_keys_.clear(); }
void MaterialManager::PrepareToRender() { used_keys_.clear(); }
void MaterialManager::EndFrame() {
void MaterialManager::RemoveUnusedMaterials() {
if (instances_.size() == used_keys_.size()) {
return;
}
@@ -102,6 +109,15 @@ static MaterialManager::MaterialKey BuildMaterialKey(
uint64_t key = hash(material);
Combine(key, &geom_type);
Combine(key, &material_type);
Combine(key, material.color_texture);
Combine(key, material.opacity_texture);
Combine(key, material.normal_texture);
Combine(key, material.orm_texture);
Combine(key, material.metallic_texture);
Combine(key, material.roughness_texture);
Combine(key, material.occlusion_texture);
Combine(key, material.emissive_texture);
Combine(key, material.reflection_texture);
return key;
}
+2 -2
View File
@@ -52,10 +52,10 @@ class MaterialManager {
// Marks the beginning of a new frame, allowing us to track which
// MaterialInstances are used during the frame so they can be removed at the
// end of the frame.
void BeginFrame();
void PrepareToRender();
// Removes any unused MaterialInstances.
void EndFrame();
void RemoveUnusedMaterials();
// Returns a MaterialType that best matches the given material data and mesh.
MaterialType GetMaterialType(const mjrfMaterial& material, const Mesh* mesh);
+4 -1
View File
@@ -14,6 +14,7 @@
#include "render/filament/core/texture.h"
#include <atomic>
#include <cstddef>
#include <cstdint>
#include <cstring>
@@ -28,6 +29,8 @@
namespace mujoco {
static std::atomic<uint64_t> g_next_texture_id{1};
static constexpr int kNumFacesPerCube = 6;
static bool IsCompressed(const mjrfTextureConfig& config) {
@@ -115,7 +118,7 @@ static filament::Texture::InternalFormat GetTextureInternalFormat(
Texture::Texture(filament::Engine* engine, const mjrfTextureConfig& config,
InternalFlags flags)
: engine_(engine), config_(config) {
: id_(g_next_texture_id++), engine_(engine), config_(config) {
if (IsCompressed(config_)) {
// We defer creation of compressed textures until Upload() is called. In
// the meantime, we don't really know anything about the texture (e.g.
+5
View File
@@ -15,6 +15,7 @@
#ifndef MUJOCO_SRC_RENDER_FILAMENT_CORE_TEXTURE_H_
#define MUJOCO_SRC_RENDER_FILAMENT_CORE_TEXTURE_H_
#include <cstdint>
#include <filament/Engine.h>
#include <filament/Texture.h>
#include <math/vec3.h>
@@ -57,6 +58,9 @@ class Texture : public mjrfTexture {
// Returns the underlying filament texture.
filament::Texture* GetFilamentTexture() const { return texture_; }
// Returns the unique id of the texture.
uint64_t Id() const { return id_; }
// Returns any spherical harmonics data associated with the texture.
using SphericalHarmonics = filament::math::float3[9];
const SphericalHarmonics* GetSphericalHarmonics() const {
@@ -73,6 +77,7 @@ class Texture : public mjrfTexture {
private:
void ReleaseData();
uint64_t id_ = 0;
filament::Engine* engine_ = nullptr;
filament::Texture* texture_ = nullptr;
mjrfTextureConfig config_;