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:
committed by
Copybara-Service
parent
29b49991a2
commit
3e33f93ddc
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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_;
|
||||
|
||||
Reference in New Issue
Block a user