mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-26 18:31:11 +00:00
Harden the GL canvases against dropped frames and UI-thread freezes
Viewport: GLCanvas3D::on_idle() cleared m_dirty even when _refresh_if_shown_on_screen() rendered nothing because the canvas was not on screen yet — a frame requested while the notebook was still showing a page got silently swallowed and the viewport stayed blank until some later event dirtied it again. _refresh_if_shown_on_screen() now reports whether it rendered, and on_idle keeps the canvas dirty when it did not. Covers Design/Prepare/Preview. Freeze: a big STEP (17.8 MB) spent ~40-50 s inside OCCT on the UI thread (read_step_solids + recompute), so the window stopped repainting and the compositor marked the app unresponsive. Both now run on a worker thread behind an app-modal pulsing progress dialog: the UI keeps painting and the document cannot be touched while the worker owns it. OCCT's Standard_Failure is not a std::exception, so the worker catches it explicitly — an escaping exception would terminate the process. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVzKmX6Y1aEteit1HTXG4Q
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
6d9368276c
commit
01aa6903f0
@@ -3267,7 +3267,10 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt)
|
||||
m_last_frame_start_time = now;
|
||||
}
|
||||
|
||||
_refresh_if_shown_on_screen();
|
||||
// Not on screen yet (e.g. the notebook is still showing this page): nothing was rendered,
|
||||
// so keep the frame pending instead of dropping it — clearing m_dirty here leaves the
|
||||
// canvas blank until some later event happens to dirty it again.
|
||||
const bool rendered = _refresh_if_shown_on_screen();
|
||||
|
||||
#if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
|
||||
if (m_extra_frame_requested || mouse3d_controller_applied || imgui_requires_extra_frame || wxGetApp().imgui()->requires_extra_frame()) {
|
||||
@@ -3279,7 +3282,7 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt)
|
||||
evt.RequestMore();
|
||||
}
|
||||
else
|
||||
m_dirty = false;
|
||||
m_dirty = !rendered;
|
||||
}
|
||||
|
||||
void GLCanvas3D::on_char(wxKeyEvent& evt)
|
||||
@@ -7251,16 +7254,18 @@ void GLCanvas3D::_update_camera_zoom(double zoom)
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
void GLCanvas3D::_refresh_if_shown_on_screen()
|
||||
bool GLCanvas3D::_refresh_if_shown_on_screen()
|
||||
{
|
||||
if (_is_shown_on_screen()) {
|
||||
const Size& cnv_size = get_canvas_size();
|
||||
_resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height());
|
||||
if (!_is_shown_on_screen())
|
||||
return false;
|
||||
|
||||
// Because of performance problems on macOS, where PaintEvents are not delivered
|
||||
// frequently enough, we call render() here directly when we can.
|
||||
render();
|
||||
}
|
||||
const Size& cnv_size = get_canvas_size();
|
||||
_resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height());
|
||||
|
||||
// Because of performance problems on macOS, where PaintEvents are not delivered
|
||||
// frequently enough, we call render() here directly when we can.
|
||||
render();
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLCanvas3D::_picking_pass()
|
||||
|
||||
Reference in New Issue
Block a user