Skip to content

Commit ed61c8a

Browse files
committed
Fix modal measurement picks under Vulkan
1 parent 7632041 commit ed61c8a

7 files changed

Lines changed: 123 additions & 4 deletions

File tree

src/python/lfs/py_ui.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,7 +938,10 @@ namespace lfs::python {
938938
}
939939
try {
940940
PyEvent py_event = convert_modal_event(event);
941+
const auto redraw_generation_before = lfs::python::redraw_request_generation();
941942
nb::object result = instance.attr("modal")(nb::none(), py_event);
943+
if (lfs::python::redraw_request_generation() != redraw_generation_before)
944+
lfs::python::request_pre_scene_panel_sync();
942945
const auto status = parse_operator_result(result, instance);
943946
if (has_undo && status == vis::op::OperatorResult::FINISHED) {
944947
push_python_operator_undo_entry(label.empty() ? class_id : label, instance);

src/python/python_runtime.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ namespace lfs::python {
177177

178178
// Redraw request flag
179179
std::atomic<bool> g_redraw_requested{false};
180+
std::atomic<uint64_t> g_redraw_generation{0};
181+
std::atomic<uint64_t> g_pre_scene_panel_sync_generation{0};
180182
MainLoopWakeCallback g_main_loop_wake_callback = nullptr;
181183
} // namespace
182184

@@ -213,6 +215,7 @@ namespace lfs::python {
213215
// Redraw request mechanism
214216
void request_redraw() {
215217
const bool was_requested = g_redraw_requested.exchange(true, std::memory_order_acq_rel);
218+
g_redraw_generation.fetch_add(1, std::memory_order_acq_rel);
216219
if (!was_requested && g_main_loop_wake_callback)
217220
g_main_loop_wake_callback();
218221
}
@@ -221,6 +224,19 @@ namespace lfs::python {
221224
return g_redraw_requested.exchange(false, std::memory_order_acq_rel);
222225
}
223226

227+
uint64_t redraw_request_generation() {
228+
return g_redraw_generation.load(std::memory_order_acquire);
229+
}
230+
231+
void request_pre_scene_panel_sync() {
232+
g_pre_scene_panel_sync_generation.store(redraw_request_generation(),
233+
std::memory_order_release);
234+
}
235+
236+
uint64_t pre_scene_panel_sync_generation() {
237+
return g_pre_scene_panel_sync_generation.load(std::memory_order_acquire);
238+
}
239+
224240
void set_main_loop_wake_callback(MainLoopWakeCallback cb) {
225241
g_main_loop_wake_callback = cb;
226242
}

src/python/python_runtime.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ namespace lfs::python {
9090
// UI redraw request mechanism
9191
LFS_PYTHON_RUNTIME_API void request_redraw();
9292
LFS_PYTHON_RUNTIME_API bool consume_redraw_request();
93+
LFS_PYTHON_RUNTIME_API uint64_t redraw_request_generation();
94+
LFS_PYTHON_RUNTIME_API void request_pre_scene_panel_sync();
95+
LFS_PYTHON_RUNTIME_API uint64_t pre_scene_panel_sync_generation();
9396
using MainLoopWakeCallback = void (*)();
9497
LFS_PYTHON_RUNTIME_API void set_main_loop_wake_callback(MainLoopWakeCallback cb);
9598

src/visualizer/gui/gui_manager.cpp

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6610,6 +6610,102 @@ namespace lfs::vis::gui {
66106610
now >= next_vram_hud_publish_);
66116611
}
66126612

6613+
void GuiManager::syncVisiblePanelsBeforeSceneRender() {
6614+
const std::uint64_t sync_generation = lfs::python::pre_scene_panel_sync_generation();
6615+
if (sync_generation == 0 ||
6616+
sync_generation == last_pre_scene_panel_sync_generation_)
6617+
return;
6618+
last_pre_scene_panel_sync_generation_ = sync_generation;
6619+
6620+
if (!viewer_ || !show_main_panel_ || ui_hidden_) {
6621+
return;
6622+
}
6623+
6624+
auto& reg = PanelRegistry::instance();
6625+
const auto main_tabs = reg.get_panels_for_space(PanelSpace::MainPanelTab);
6626+
if (main_tabs.empty()) {
6627+
return;
6628+
}
6629+
6630+
panel_layout_.syncActiveTab(main_tabs, focus_panel_name_);
6631+
const std::string& active_tab = panel_layout_.getActiveTab();
6632+
if (active_tab.empty()) {
6633+
return;
6634+
}
6635+
6636+
const ImGuiViewport* const mvp = ImGui::GetMainViewport();
6637+
if (!mvp || mvp->WorkSize.x <= 0.0f || mvp->WorkSize.y <= 0.0f) {
6638+
return;
6639+
}
6640+
6641+
auto& editor_ctx = viewer_->getEditorContext();
6642+
auto* scene_manager = viewer_->getSceneManager();
6643+
auto* trainer_manager = viewer_->getTrainerManager();
6644+
editor_ctx.update(scene_manager, trainer_manager);
6645+
6646+
UIContext ctx{
6647+
.viewer = viewer_,
6648+
.window_states = &window_states_,
6649+
.editor = &editor_ctx,
6650+
.sequencer_controller = &sequencer_ui_.controller(),
6651+
.rml_manager = &rmlui_manager_,
6652+
.fonts = buildFontSet()};
6653+
6654+
lfs::core::Scene* scene = nullptr;
6655+
if (scene_manager)
6656+
scene = &scene_manager->getScene();
6657+
6658+
PanelDrawContext draw_ctx;
6659+
draw_ctx.ui = &ctx;
6660+
draw_ctx.viewport = &viewport_layout_;
6661+
draw_ctx.scene = scene;
6662+
draw_ctx.ui_hidden = ui_hidden_;
6663+
draw_ctx.scene_generation = python::get_scene_generation();
6664+
if (scene_manager)
6665+
draw_ctx.has_selection = scene_manager->hasSelectedNode();
6666+
if (auto* cc = lfs::event::command_center())
6667+
draw_ctx.is_training = cc->snapshot().is_running;
6668+
6669+
PanelInputState input;
6670+
input.mouse_x = -1.0e9f;
6671+
input.mouse_y = -1.0e9f;
6672+
input.screen_x = mvp->Pos.x;
6673+
input.screen_y = mvp->Pos.y;
6674+
input.screen_w = static_cast<int>(mvp->Size.x);
6675+
input.screen_h = static_cast<int>(mvp->Size.y);
6676+
6677+
const float dpi = lfs::python::get_shared_dpi_scale();
6678+
const float panel_h = mvp->WorkSize.y - PanelLayoutManager::STATUS_BAR_HEIGHT * dpi;
6679+
if (panel_h <= 0.0f) {
6680+
return;
6681+
}
6682+
6683+
constexpr float kPanelPad = 8.0f;
6684+
constexpr float kPreloadMaxHeight = 100000.0f;
6685+
const float content_w = panel_layout_.getRightPanelWidth() - 2.0f * kPanelPad;
6686+
if (content_w <= 0.0f) {
6687+
return;
6688+
}
6689+
6690+
const float splitter_h = PanelLayoutManager::SPLITTER_H * dpi;
6691+
const float tab_bar_h = PanelLayoutManager::TAB_BAR_H * dpi;
6692+
const float avail_h = panel_h - 2.0f * kPanelPad;
6693+
const float scene_h =
6694+
std::max(80.0f * dpi,
6695+
avail_h * panel_layout_.getScenePanelRatio() - splitter_h * 0.5f);
6696+
const float content_top = mvp->WorkPos.y + kPanelPad;
6697+
const float tab_content_y = content_top + scene_h + splitter_h + tab_bar_h;
6698+
const float tab_content_h =
6699+
std::max(0.0f, content_top + avail_h - tab_content_y);
6700+
const float clip_y_min = tab_content_y;
6701+
const float clip_y_max = tab_content_y + tab_content_h;
6702+
6703+
reg.preload_single_panel_direct(active_tab, content_w, kPreloadMaxHeight, draw_ctx,
6704+
clip_y_min, clip_y_max, &input);
6705+
reg.preload_child_panels_direct(active_tab, content_w, kPreloadMaxHeight, draw_ctx,
6706+
clip_y_min, clip_y_max, &input);
6707+
}
6708+
66136709
bool GuiManager::needsAnimationFrame() const {
66146710
if (isViewportExportLocked())
66156711
return true;

src/visualizer/gui/gui_manager.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ namespace lfs::vis {
7777
void init();
7878
void shutdown();
7979
void render();
80+
void syncVisiblePanelsBeforeSceneRender();
8081
void setRmlResizeDeferring(bool defer) { rmlui_manager_.setResizeDeferring(defer); }
8182

8283
// Sub-manager access
@@ -382,6 +383,7 @@ namespace lfs::vis {
382383
RightPanelPointerRegion::None;
383384
bool bottom_dock_pointer_live_capture_ = false;
384385
std::string last_ui_layout_active_tab_;
386+
std::uint64_t last_pre_scene_panel_sync_generation_ = 0;
385387

386388
struct DevResourceWatchState {
387389
bool enabled = false;

src/visualizer/rendering/vksplat_viewport_renderer.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3577,10 +3577,6 @@ namespace lfs::vis {
35773577
return -1.0f;
35783578
}
35793579

3580-
if (!context.waitForSubmittedFrames()) {
3581-
return std::unexpected(context.lastError());
3582-
}
3583-
35843580
const VkDevice device = context.device();
35853581
constexpr VkDeviceSize byte_count = sizeof(float);
35863582
ScopedStagingBuffer staging{};

src/visualizer/visualizer_impl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,6 +1366,9 @@ namespace lfs::vis {
13661366
}
13671367

13681368
if (!viewport_export_locked) {
1369+
if (frame_demand.python_redraw && gui_manager_)
1370+
gui_manager_->syncVisiblePanelsBeforeSceneRender();
1371+
13691372
const auto vulkan_frame = rendering_manager_->renderVulkanFrame(context);
13701373
if (gui_manager_) {
13711374
if (vulkan_frame.external_image != VK_NULL_HANDLE) {

0 commit comments

Comments
 (0)