From ecb15a8d9e21108762a5a128ff6a27e1e326bd3f Mon Sep 17 00:00:00 2001 From: Haroon Qureshi Date: Tue, 9 Jun 2026 09:09:30 -0700 Subject: [PATCH] Cache the render targets. PiperOrigin-RevId: 929230223 Change-Id: I06571687ba0153c6ee8631685d1d37052419d2ac --- src/experimental/filament/mjr_compat.cc | 42 +++++++++++-------- .../filament/render_context_filament.cc | 5 +++ .../filament/render_context_filament.h | 3 ++ 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/experimental/filament/mjr_compat.cc b/src/experimental/filament/mjr_compat.cc index db328491..f8fdda6a 100644 --- a/src/experimental/filament/mjr_compat.cc +++ b/src/experimental/filament/mjr_compat.cc @@ -62,6 +62,8 @@ class CompatContext { UniquePtr context_; std::unique_ptr scene_bridge_; mjtFramebuffer framebuffer_ = mjFB_WINDOW; + UniquePtr color_target_{nullptr, nullptr}; + UniquePtr depth_target_{nullptr, nullptr}; }; CompatContext::CompatContext(const mjrFilamentConfig* config, @@ -104,14 +106,18 @@ void CompatContext::ReadPixels(mjrRect viewport, unsigned char* rgb, mju_error("ReadPixels is only supported for offscreen rendering."); } + const int width = viewport.width; + const int height = viewport.height; + if (rgb) { - mjrfRenderTargetConfig config; - mjrf_defaultRenderTargetConfig(&config); - config.width = viewport.width; - config.height = viewport.height; - config.color_format = mjPIXEL_FORMAT_RGB8; - config.depth_format = mjPIXEL_FORMAT_DEPTH32F; - auto target = CreateRenderTarget(context_.get(), config); + if (!color_target_) { + mjrfRenderTargetConfig config; + mjrf_defaultRenderTargetConfig(&config); + config.color_format = mjPIXEL_FORMAT_RGB8; + config.depth_format = mjPIXEL_FORMAT_DEPTH32F; + color_target_ = CreateRenderTarget(context_.get(), config); + } + mjrf_resizeRenderTarget(color_target_.get(), width, height); mjrfRenderRequest req; mjrf_defaultRenderRequest(&req); @@ -119,11 +125,11 @@ void CompatContext::ReadPixels(mjrRect viewport, unsigned char* rgb, req.draw_mode = draw_mode_; req.camera = scene_bridge_->GetCamera(); req.viewport = viewport; - req.target = target.get(); + req.target = color_target_.get(); mjrfReadPixelsRequest read_req; mjrf_defaultReadPixelsRequest(&read_req); - read_req.target = target.get(); + read_req.target = color_target_.get(); read_req.output = rgb; read_req.num_bytes = viewport.width * viewport.height * 3; @@ -132,13 +138,14 @@ void CompatContext::ReadPixels(mjrRect viewport, unsigned char* rgb, } if (depth) { - mjrfRenderTargetConfig config; - mjrf_defaultRenderTargetConfig(&config); - config.width = viewport.width; - config.height = viewport.height; - config.color_format = mjPIXEL_FORMAT_R32F; - config.depth_format = mjPIXEL_FORMAT_DEPTH32F; - auto target = CreateRenderTarget(context_.get(), config); + if (!depth_target_) { + mjrfRenderTargetConfig config; + mjrf_defaultRenderTargetConfig(&config); + config.color_format = mjPIXEL_FORMAT_R32F; + config.depth_format = mjPIXEL_FORMAT_DEPTH32F; + depth_target_ = CreateRenderTarget(context_.get(), config); + } + mjrf_resizeRenderTarget(depth_target_.get(), width, height); mjrfRenderRequest req; mjrf_defaultRenderRequest(&req); @@ -146,10 +153,11 @@ void CompatContext::ReadPixels(mjrRect viewport, unsigned char* rgb, req.draw_mode = mjDRAW_MODE_DEPTH; req.camera = scene_bridge_->GetCamera(); req.viewport = viewport; - req.target = target.get(); + req.target = depth_target_.get(); mjrfReadPixelsRequest read_req; mjrf_defaultReadPixelsRequest(&read_req); + read_req.target = depth_target_.get(); read_req.output = reinterpret_cast(depth); read_req.num_bytes = viewport.width * viewport.height * sizeof(float); diff --git a/src/experimental/filament/render_context_filament.cc b/src/experimental/filament/render_context_filament.cc index c21d190c..d653b50f 100644 --- a/src/experimental/filament/render_context_filament.cc +++ b/src/experimental/filament/render_context_filament.cc @@ -292,6 +292,11 @@ void mjrf_configureSceneFromModel(mjrfScene* scene, const mjModel* model) { mujoco::SceneView::downcast(scene)->Configure(model); } +void mjrf_resizeRenderTarget(mjrfRenderTarget* render_target, int width, + int height) { + mujoco::RenderTarget::downcast(render_target)->Prepare(width, height); +} + mjrfFrameHandle mjrf_render(mjrfContext* ctx, const mjrfRenderRequest* req, int nreq, const mjrfReadPixelsRequest* read_req, int nread_req) { diff --git a/src/experimental/filament/render_context_filament.h b/src/experimental/filament/render_context_filament.h index 89031dd9..461042c9 100644 --- a/src/experimental/filament/render_context_filament.h +++ b/src/experimental/filament/render_context_filament.h @@ -466,6 +466,9 @@ mjrfRenderTarget* mjrf_createRenderTarget(mjrfContext* ctx, const mjrfRenderTarg // Destroys the render target. void mjrf_destroyRenderTarget(mjrfRenderTarget* render_target); +// Resizes the render target to the given width and height. +void mjrf_resizeRenderTarget(mjrfRenderTarget* render_target, int width, int height); + // ## Debug-only functions. // Draws an ImGui editor for the given scene, exposing filament-specific settings.