Create material instances for each draw call rather than for each clip rect.

This fixes a bug where the wrong instance was being used in some cases.

PiperOrigin-RevId: 833818151
Change-Id: If8b0cb90017ee0b89cde98a5ae64c36704c7338c
This commit is contained in:
Haroon Qureshi
2025-11-18 08:16:02 -08:00
committed by Copybara-Service
parent 62872fecd1
commit 7569ac960d
2 changed files with 13 additions and 21 deletions
+11 -19
View File
@@ -64,7 +64,7 @@ GuiView::GuiView(filament::Engine* engine, ObjectManager* object_mgr)
GuiView::~GuiView() { GuiView::~GuiView() {
ResetRenderable(); ResetRenderable();
for (auto& instance : instances_) { for (auto& instance : instances_) {
engine_->destroy(instance.second); engine_->destroy(instance);
} }
engine_->destroyCameraComponent(camera_->getEntity()); engine_->destroyCameraComponent(camera_->getEntity());
engine_->destroy(view_); engine_->destroy(view_);
@@ -166,7 +166,8 @@ bool GuiView::PrepareRenderable() {
} }
mjrRect clip_rect{clip_left, clip_bottom, clip_width, clip_height}; mjrRect clip_rect{clip_left, clip_bottom, clip_width, clip_height};
builder.material(drawable_index, GetMaterialInstance(clip_rect)); builder.material(drawable_index,
GetMaterialInstance(drawable_index, clip_rect));
builder.geometry(drawable_index, kTriangles, buffer.vertex_buffer, builder.geometry(drawable_index, kTriangles, buffer.vertex_buffer,
buffer.index_buffer, index_offset, buffer.index_buffer, index_offset,
command.ElemCount); command.ElemCount);
@@ -184,26 +185,17 @@ bool GuiView::PrepareRenderable() {
return true; return true;
} }
// Maps a rect into a 64-bit key to assist with lookup. filament::MaterialInstance* GuiView::GetMaterialInstance(int index,
static uint64_t MakeRectKey(mjrRect rect) { mjrRect rect) {
return static_cast<uint64_t>(rect.left & 0xff) << 24 | while (index >= instances_.size()) {
static_cast<uint64_t>(rect.bottom & 0xff) << 16 | filament::TextureSampler sampler;
static_cast<uint64_t>(rect.width & 0xff) << 8 | filament::MaterialInstance* instance = material_->createInstance();
static_cast<uint64_t>(rect.height & 0xff); instance->setParameter("glyph", object_mgr_->GetFont(0), sampler);
} instances_.push_back(instance);
filament::MaterialInstance* GuiView::GetMaterialInstance(mjrRect rect) {
const uint64_t key = MakeRectKey(rect);
auto iter = instances_.find(key);
if (iter != instances_.end()) {
return iter->second;
} }
auto instance = material_->createInstance(); filament::MaterialInstance* instance = instances_[index];
instance->setScissor(rect.left, rect.bottom, rect.width, rect.height); instance->setScissor(rect.left, rect.bottom, rect.width, rect.height);
filament::TextureSampler sampler;
instance->setParameter("glyph", object_mgr_->GetFont(0), sampler);
instances_[key] = instance;
return instance; return instance;
} }
@@ -49,7 +49,7 @@ class GuiView {
private: private:
// Returns the filament::MaterialInstance configured to draw into the given // Returns the filament::MaterialInstance configured to draw into the given
// scissor rect. // scissor rect.
filament::MaterialInstance* GetMaterialInstance(mjrRect rect); filament::MaterialInstance* GetMaterialInstance(int index, mjrRect rect);
// Clears the filament::Scene of the UX renderable and releases all buffers. // Clears the filament::Scene of the UX renderable and releases all buffers.
void ResetRenderable(); void ResetRenderable();
@@ -62,7 +62,7 @@ class GuiView {
filament::Material* material_ = nullptr; filament::Material* material_ = nullptr;
utils::Entity renderable_; utils::Entity renderable_;
std::vector<FilamentBuffers> buffers_; std::vector<FilamentBuffers> buffers_;
std::unordered_map<uint64_t, filament::MaterialInstance*> instances_; std::vector<filament::MaterialInstance*> instances_;
}; };
// Draws text at the given screen coordinates in clip space (i.e. [-1,-1,-1] to // Draws text at the given screen coordinates in clip space (i.e. [-1,-1,-1] to