SLADE
SLADE copied to clipboard
SLADE performance gradually degrades until it's unusable
SLADE Version: master, for months Operating System: Arch Linux x64
Issue Details:
If I leave SLADE open for a couple hours, even if it's completely idle, it will gradually consume more CPU time and take longer to redraw until it's nigh unusable. Even closing it is harder, because the "do you want to exit" dialog doesn't draw its contents (despite the window itself opening immediately).
I've thrown everything I can think of at this and have absolutely no idea what's going on. Both perf
and manual inspection with gdb
blame most of the time on an unnamed function a couple calls below g_main_context_check
, e.g. perf report
shows:
80.21% 0x7f49cc1926d7
6.95% 0x7f49cc192677
4.20% g_main_context_check
4.12% g_main_context_prepare
0.88% 0x7f49cc1926f3
But this is just part of glib's main loop, which should be poll()
ing and not eating up any real CPU time.
Doesn't like to reproduce unless I'm not trying to reproduce it, which makes bisecting difficult. Seems to happen faster if I'm actively using the map editor, but that might be my imagination. Regardless, SLADE is practically unusable for any real work like this.
Would love some suggestions, because I'm out of ideas.
Not sure if this is helpful, but this only seems to happen when map editor is left open. Have left the main part of Slade open overnight with no problems, but map editor will pretty consistently grind to a near-halt.
I want to say it's happened once or twice with only an archive open (and no map editor), but I haven't been keeping super detailed notes or anything.
Haven't noticed this problem on Windows, so it's probably Linux-specific.
If it is actually linux-only (or non-windows-only) it may be something to do with either the wxGLCanvas implementation of OGLCanvas, or the FTGL font rendering implementation
The FTGL hypothesis can be tested by removing it and stubbing out functions that use it -- for a test it's not a problem if the map editor no longer displays any text, as long as it can be opened and left running for a while to see if the problem persists.
Would early returning from Drawing::drawText
be enough?
It's happened to me on Windows 10, but only with the map editor as far as I can tell.
Actually this is from a release or two ago, I haven't left it open since then. I'll leave it running again tonight and see what happens.
(BTW, have used FTGL pretty extensively in one of my own projects and never had an issue like this, but it was a few years ago... something could have cropped up since then)
Early returning from Drawing::drawText
did not fix it. Also it looks like I can reproduce pretty reliably by just leaving the map editor open for 24 hours. Worst possible debug cycle. :)
Ahhhh I knew I wasn't alone on this. Good catch.
Still happening on master, even just from leaving it open with a single archive loaded. :( And still no idea why.
Does the memory usage also go up along with this? I assume it does otherwise this really doesn't make any sense.
I could add some kind of diagnostic console command that dumps a bunch of info about the current map editor state if it would help
Hello,
I would like to report that is issue is still happening on the latest version of Slade.
The map editor use a lot of power right from the start, on any maps, and can become unusable to the point that only a complete restart of the software will fix this issue.
I ran perf
on the latest revision of Slade.
# Total Lost Samples: 0
#
# Samples: 2M of event 'cycles:u'
# Event count (approx.): 417264634100
#
# Overhead Samples Command Shared Object Symbol
# ........ ............ ............... ................................... ............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
#
4.57% 95371 slade libwx_baseu-3.0.so.0.4.0 [.] wxEvtHandler::SearchDynamicEventTable
2.78% 57694 slade libwx_gtk3u_core-3.0.so.0.4.0 [.] wxWindowBase::SendIdleEvents
1.28% 22331 slade libpango-1.0.so.0.4400.7 [.] pango_default_break
1.23% 27062 slade libwx_baseu-3.0.so.0.4.0 [.] wxEventHashTable::HandleEvent
1.14% 24906 slade libc-2.31.so [.] __memcmp_avx2_movbe
0.74% 15812 slade slade [.] std::less<int>::operator()
0.72% 13987 slade slade [.] MapObject::modifiedTime
0.72% 14563 slade [unknown] [.] 0000000000000000
0.54% 11699 slade slade [.] MapLine::seg
0.50% 11013 slade libstdc++.so.6.0.28 [.] std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::compare
0.47% 10847 slade slade [.] std::_Rb_tree<int, std::pair<int const, Game::ThingType>, std::_Select1st<std::pair<int const, Game::ThingType> >, std::less<int>, std::allocator<std::pair<int const, Game::ThingType> > >::_M_lower_bound
0.44% 8944 slade libgobject-2.0.so.0.6400.1 [.] g_type_check_instance_is_a
0.42% 8734 slade libgtk-3.so.0.2407.7 [.] gtk_widget_get_child_visible
0.42% 9291 slade libwx_baseu-3.0.so.0.4.0 [.] wxEvtHandler::TryHereOnly
0.41% 9203 slade libpthread-2.31.so [.] __pthread_mutex_lock
Best regards.
For additional information, I've compiled Slade using gprof
.
Here is the flat profile:
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ms/call ms/call name
4.08 0.13 0.13 3643166 0.00 0.00 MapObject::modifiedTime() const
2.51 0.21 0.08 1778731 0.00 0.00 MapLine::seg() const
2.51 0.29 0.08 wxEvtHandler::TryValidator(wxEvent&)
2.19 0.36 0.07 1644333 0.00 0.00 MathStuff::closestPointOnLine(Vec2<double>, Rect<double>)
1.88 0.42 0.06 1939015 0.00 0.00 MapObject::index() const
1.57 0.47 0.05 5489502 0.00 0.00 MapVertex::position() const
1.57 0.52 0.05 4124283 0.00 0.00 bool std::operator==<char, std::char_traits<char> >(std::common_type<std::basic_string_view<char, std::char_traits<char> > >::type, std::basic_string_view<char, std::char_traits<char> >)
1.57 0.57 0.05 2332545 0.00 0.00 MapVertex::xPos() const
1.57 0.62 0.05 2201 0.02 0.07 MapRenderer3D::determineHilight()
1.25 0.66 0.04 2515937 0.00 0.00 bool __gnu_cxx::operator!=<KeyBind*, std::vector<KeyBind, std::allocator<KeyBind> > >(__gnu_cxx::__normal_iterator<KeyBind*, std::vector<KeyBind, std::allocator<KeyBind> > > const&, __gnu_cxx::__normal_iterator<KeyBind*, std::vector<KeyBind, std::allocator<KeyBind> > > const&)
1.25 0.70 0.04 639872 0.00 0.00 MapLine::end() const
1.25 0.74 0.04 wxTopLevelWindowBase::IsTopLevel() const
0.94 0.77 0.03 2497532 0.00 0.00 __gnu_cxx::__normal_iterator<KeyBind*, std::vector<KeyBind, std::allocator<KeyBind> > >::operator++()
0.94 0.80 0.03 752977 0.00 0.00 std::char_traits<char>::length(char const*)
0.94 0.83 0.03 713142 0.00 0.00 MapSide::sector() const
0.94 0.86 0.03 445842 0.00 0.00 MapRenderer3D::setFog(ColRGBA&, unsigned char)
0.94 0.89 0.03 127 0.24 0.32 SIFPng::readImage(SImage&, MemChunk&, int)
0.94 0.92 0.03 wxEvtHandler::AddPendingEvent(wxEvent const&)
0.94 0.95 0.03 wxTopLevelWindowBase::ShouldPreventAppExit() const
0.78 0.98 0.03 5058503 0.00 0.00 MemChunk::operator[](int) const
0.78 1.00 0.03 4420455 0.00 0.00 Rect<double>::height() const
0.78 1.03 0.03 197202 0.00 0.00 std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, ColourConfiguration::Colour>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, ColourConfiguration::Colour> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, ColourConfiguration::Colour> > >::end()
0.63 1.05 0.02 2598984 0.00 0.00 __gnu_cxx::__normal_iterator<MapLine* const*, std::vector<MapLine*, std::allocator<MapLine*> > >::operator++()
0.63 1.07 0.02 2425647 0.00 0.00 MapObjectCollection::lines() const
0.63 1.09 0.02 1381739 0.00 0.00 MathStuff::distanceToLine(Vec2<double>, Rect<double>)
0.63 1.11 0.02 1304350 0.00 0.00 ColRGBA::fb() const
0.63 1.13 0.02 1304350 0.00 0.00 ColRGBA::fr() const
0.63 1.15 0.02 740887 0.00 0.00 bool __gnu_cxx::operator!=<MapRenderer3D::Quad*, std::vector<MapRenderer3D::Quad, std::allocator<MapRenderer3D::Quad> > >(__gnu_cxx::__normal_iterator<MapRenderer3D::Quad*, std::vector<MapRenderer3D::Quad, std::allocator<MapRenderer3D::Quad> > > const&, __gnu_cxx::__normal_iterator<MapRenderer3D::Quad*, std::vector<MapRenderer3D::Quad, std::allocator<MapRenderer3D::Quad> > > const&)
0.63 1.17 0.02 712701 0.00 0.00 MapLine::distanceTo(Vec2<double>)
0.63 1.19 0.02 647421 0.00 0.00 CIntCVar::operator int() const
0.63 1.21 0.02 595058 0.00 0.00 std::vector<Polygon2D::Vertex, std::allocator<Polygon2D::Vertex> >::size() const
0.63 1.23 0.02 424778 0.00 0.00 MathStuff::distanceRayLine(Vec2<double>, Vec2<double>, Vec2<double>, Vec2<double>)
0.63 1.25 0.02 83555 0.00 0.00 wxLongLongNative::operator/(long) const
0.63 1.27 0.02 44291 0.00 0.00 App::resources()
0.63 1.29 0.02 8637 0.00 0.19 MapEditor::Renderer::draw()
0.63 1.31 0.02 6535 0.00 0.03 MapRenderer2D::renderFlatsVBO(int, bool, float)
0.63 1.33 0.02 6535 0.00 0.01 MapEditor::Renderer::drawGrid() const
0.63 1.35 0.02 2102 0.01 0.07 MapRenderer3D::quickVisDiscard()
0.63 1.37 0.02 2102 0.01 0.09 MapRenderer3D::checkVisibleQuads()
0.63 1.39 0.02 52 0.38 0.38 fmt::v5::basic_format_args<fmt::v5::basic_format_context<std::back_insert_iterator<fmt::v5::internal::basic_buffer<char> >, char> >::basic_format_args<>(fmt::v5::format_arg_store<fmt::v5::basic_format_context<std::back_insert_iterator<fmt::v5::internal::basic_buffer<char> >, char>> const&)
And here is the call graph:
Call graph (explanation follows)
granularity: each sample hit covers 2 byte(s) for 0.31% of 3.19 seconds
index % time self children called name
<spontaneous>
[1] 53.1 0.01 1.68 OGLCanvas::onPaint(wxPaintEvent&) [1]
0.01 1.66 8637/8637 MapCanvas::draw() [2]
0.00 0.01 8646/8649 OGLCanvas::setActive() [308]
0.00 0.00 9/9 MapPreviewCanvas::draw() [837]
0.00 0.00 2/2 OGLCanvas::init() [1577]
0.00 0.00 8646/15181 OpenGL::resetBlend() [10778]
0.00 0.00 8646/10277 wxPaintDC::~wxPaintDC() [11066]
-----------------------------------------------
0.01 1.66 8637/8637 OGLCanvas::onPaint(wxPaintEvent&) [1]
[2] 52.5 0.01 1.66 8637 MapCanvas::draw() [2]
0.02 1.64 8637/8637 MapEditor::Renderer::draw() [3]
0.00 0.00 8637/18677 MapEditContext::renderer() [10698]
-----------------------------------------------
0.02 1.64 8637/8637 MapCanvas::draw() [2]
[3] 52.2 0.02 1.64 8637 MapEditor::Renderer::draw() [3]
0.00 0.80 6535/6535 MapEditor::Renderer::drawMap2d() [4]
0.00 0.69 2102/2102 MapEditor::Renderer::drawMap3d() [5]
0.00 0.12 8637/8637 MapEditContext::drawInfoOverlay(Vec2<int> const&, float) [22]
0.01 0.02 8637/8637 MapEditor::Renderer::drawEditorMessages() const [115]
0.00 0.00 8637/170757 ColourConfiguration::colour(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [89]
0.00 0.00 2102/9036 ColourConfiguration::colDef(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) [498]
0.00 0.00 8637/8637 MapEditor::Renderer::drawFeatureHelpText() const [768]
0.00 0.00 17274/177047 MapEditContext::editMode() const [359]
0.00 0.00 10739/211748 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<std::allocator<char> >(char const*, std::allocator<char> const&) [213]
0.00 0.00 17045/1304350 ColRGBA::fb() const [197]
0.00 0.00 17045/1304350 ColRGBA::fr() const [198]
0.00 0.00 2102/647421 CIntCVar::operator int() const [193]
0.00 0.00 2102/2756612 ColRGBA::ColRGBA(ColRGBA const&) [318]
0.00 0.00 47389/69043 MapEditor::RenderView::size() const [10185]
0.00 0.00 17045/1304350 ColRGBA::fg() const [9722]
0.00 0.00 10510/380411 OpenGL::setColour(ColRGBA const&, OpenGL::Blend) [9827]
0.00 0.00 8637/16863 OpenGL::accuracyTweak() [10732]
0.00 0.00 8637/10838 MapEditContext::currentOverlay() const [11031]
0.00 0.00 2102/21327 ColourConfiguration::Colour::blendMode() const [10643]
0.00 0.00 2102/18677 MapEditContext::renderer() [10698]
0.00 0.00 2102/2102 MapRenderer3D::itemDistance() const [12492]
0.00 0.00 2102/10015 MapEditor::Renderer::renderer3D() [11116]
0.00 0.00 1859/1476321 CBoolCVar::operator bool() const [9707]
-----------------------------------------------
0.00 0.80 6535/6535 MapEditor::Renderer::draw() [3]
[4] 25.1 0.00 0.80 6535 MapEditor::Renderer::drawMap2d() [4]
0.00 0.19 1452/1452 MapEditor::Renderer::drawSelectionNumbers() const [13]
0.00 0.17 6535/6535 MapRenderer2D::renderFlats(int, bool, float) [14]
0.00 0.10 6535/6551 MapRenderer2D::renderLines(bool, float) [35]
0.00 0.08 860/860 MapRenderer2D::renderMovingLines(std::vector<MapEditor::Item, std::allocator<MapEditor::Item> > const&, Vec2<double>) const [47]
0.00 0.05 6535/6535 MapRenderer2D::renderThings(float, bool) [74]
0.00 0.04 4799/4799 MapRenderer2D::renderLineSelection(ItemSelection const&, float) const [90]
0.02 0.02 6535/6535 MapEditor::Renderer::drawGrid() const [93]
0.01 0.03 876/876 MapEditor::Renderer::drawObjectEdit() [100]
0.00 0.03 6535/19974 MapRenderer2D::renderVertices(float) <cycle 3> [2305]
0.01 0.02 6535/8637 MapEditor::Renderer::drawAnimations() const [116]
0.00 0.01 6535/6535 MapRenderer2D::visOK() const [465]
0.00 0.01 6535/11364 ItemSelection::empty() const [455]
0.00 0.00 13070/31416 MapEditor::RenderView::mapY(int, bool) const [370]
0.00 0.00 8938/8996 std::vector<MapLine*, std::allocator<MapLine*> >::empty() const [702]
0.00 0.00 4469/4965 MapRenderer2D::renderLineHilight(int, float) const [746]
0.00 0.00 20512/177047 MapEditContext::editMode() const [359]
0.00 0.00 13070/647421 CIntCVar::operator int() const [193]
0.00 0.00 47/47 MapEditor::Renderer::drawPasteLines() const [920]
0.00 0.00 566/17123 ColourConfiguration::setGLColour(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, float) [463]
0.00 0.00 4/141 MapRenderer2D::updateVisibility(Vec2<double>, Vec2<double>) [696]
0.00 0.00 566/211748 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<std::allocator<char> >(char const*, std::allocator<char> const&) [213]
0.00 0.00 32675/52164 MapEditContext::input() [10267]
0.00 0.00 16679/45166 MapEditContext::overlayActive() const [10317]
0.00 0.00 13070/28310 MapEditor::Input::mousePos() const [10497]
0.00 0.00 13070/31408 MapEditor::RenderView::mapX(int, bool) const [10436]
0.00 0.00 13070/13070 MapEditor::Input::mouseDownPos() const [10864]
0.00 0.00 11334/20359 MapEditContext::selection() [10664]
0.00 0.00 8938/8938 std::vector<MapThing*, std::allocator<MapThing*> >::empty() const [11232]
0.00 0.00 6535/6535 MapEditor::RenderView::apply() const [11425]
0.00 0.00 6535/380411 OpenGL::setColour(ColRGBA const&, OpenGL::Blend) [9827]
0.00 0.00 6535/20572 MapEditor::Input::mouseState() const [10661]
0.00 0.00 6535/15181 OpenGL::resetBlend() [10778]
0.00 0.00 4469/4469 MapEditContext::hilightItem() const [11717]
0.00 0.00 4469/4469 std::vector<MapSector*, std::allocator<MapSector*> >::empty() const [11718]
0.00 0.00 4469/4469 MapEditContext::taggedSectors() [11714]
0.00 0.00 4469/4469 MapEditContext::taggedLines() [11711]
0.00 0.00 4469/4469 MapEditContext::taggedThings() [11712]
0.00 0.00 4469/4469 MapEditContext::taggingLines() [11713]
0.00 0.00 4469/4469 MapEditContext::taggingThings() [11715]
0.00 0.00 1720/1728 MapEditContext::moveObjects() [12708]
0.00 0.00 1452/1476321 CBoolCVar::operator bool() const [9707]
0.00 0.00 860/860 MoveObjects::items() const [13493]
0.00 0.00 860/860 MoveObjects::offset() const [13494]
0.00 0.00 8/302 MapEditor::RenderView::mapBounds() const [14690]
-----------------------------------------------
0.00 0.69 2102/2102 MapEditor::Renderer::draw() [3]
[5] 21.6 0.00 0.69 2102 MapEditor::Renderer::drawMap3d() [5]
0.00 0.67 2102/2102 MapRenderer3D::renderMap() [6]
0.00 0.01 2102/8637 MapEditor::Renderer::drawAnimations() const [116]
0.00 0.00 2102/2102 MapRenderer3D::setupView(int, int) [588]
0.00 0.00 1857/2813 MapRenderer3D::renderHilight(MapEditor::Item, float) [532]
0.00 0.00 2102/2102 MapRenderer3D::renderFlatSelection(ItemSelection const&, float) const [712]
0.00 0.00 2102/2102 MapRenderer3D::renderWallSelection(ItemSelection const&, float) [711]
0.00 0.00 2102/2102 MapRenderer3D::renderThingSelection(ItemSelection const&, float) [803]
0.00 0.00 2102/2102 ItemSelection::ItemSelection(ItemSelection const&) [1241]
0.00 0.00 6061/20359 MapEditContext::selection() [10664]
0.00 0.00 4204/69043 MapEditor::RenderView::size() const [10185]
0.00 0.00 2102/9409 ItemSelection::hasHilight() const [11164]
0.00 0.00 2102/2103 ItemSelection::~ItemSelection() [12480]
0.00 0.00 1857/22810 ItemSelection::hilight() const [10626]
-----------------------------------------------
0.00 0.67 2102/2102 MapEditor::Renderer::drawMap3d() [5]
[6] 20.9 0.00 0.67 2102 MapRenderer3D::renderMap() [6]
0.02 0.18 2102/2102 MapRenderer3D::checkVisibleQuads() [12]
0.02 0.14 2102/2102 MapRenderer3D::quickVisDiscard() [17]
0.00 0.13 2102/2102 MapRenderer3D::checkVisibleFlats() [20]
0.00 0.07 2102/2102 MapRenderer3D::renderFlats() [52]
0.01 0.03 2102/2102 MapRenderer3D::renderThings() [102]
0.01 0.03 2102/2102 MapRenderer3D::renderWalls() [105]
0.01 0.02 2102/2102 MapRenderer3D::renderSky() [117]
0.00 0.00 172906/1302306 MapSector::polygon() [237]
0.00 0.00 172906/1549832 SLADEMap::sector(unsigned int) const [238]
0.00 0.00 177114/1906609 SLADEMap::nSectors() const [283]
0.00 0.00 2/2 MapRenderer3D::updateFlatsVBO() [1089]
0.00 0.00 2102/647421 CIntCVar::operator int() const [193]
0.00 0.00 2104/809560 SLADEMap::nLines() const [171]
0.00 0.00 172906/1041889 Polygon2D::vboUpdate() const [9737]
0.00 0.00 6306/1476321 CBoolCVar::operator bool() const [9707]
0.00 0.00 2104/88935 SLADEMap::nThings() const [10095]
0.00 0.00 2102/275216 OpenGL::vboSupport() [9857]
0.00 0.00 2102/4328 std::vector<MapRenderer3D::Flat, std::allocator<MapRenderer3D::Flat> >::size() const [11745]
0.00 0.00 2102/521409 std::vector<MapRenderer3D::Line, std::allocator<MapRenderer3D::Line> >::size() const [9787]
0.00 0.00 2102/4316 std::vector<MapRenderer3D::Thing, std::allocator<MapRenderer3D::Thing> >::size() const [11746]
0.00 0.00 2102/380411 OpenGL::setColour(ColRGBA const&, OpenGL::Blend) [9827]
0.00 0.00 2102/2102 MapRenderer3D::renderTransparentWalls() [12487]
0.00 0.00 4/4 std::vector<MapRenderer3D::Flat, std::allocator<MapRenderer3D::Flat> >::resize(unsigned long) [24711]
0.00 0.00 2/2 std::vector<MapRenderer3D::Line, std::allocator<MapRenderer3D::Line> >::resize(unsigned long) [32865]
0.00 0.00 2/2 std::vector<MapRenderer3D::Thing, std::allocator<MapRenderer3D::Thing> >::resize(unsigned long) [32867]
-----------------------------------------------
<spontaneous>
[7] 15.9 0.01 0.50 MapCanvas::onRTimer(wxTimerEvent&) [7]
0.00 0.47 9217/9217 MapEditContext::update(long) [8]
0.00 0.03 9217/9217 MapCanvas::mouseLook3d() [119]
0.00 0.00 9217/647421 CIntCVar::operator int() const [193]
-----------------------------------------------
0.00 0.47 9217/9217 MapCanvas::onRTimer(wxTimerEvent&) [7]
[8] 14.6 0.00 0.47 9217 MapEditContext::update(long) [8]
0.05 0.11 2201/2201 MapRenderer3D::determineHilight() [16]
0.01 0.12 2201/2201 MapEditor::Input::updateCamera3d(double) const [21]
0.00 0.11 4898/4917 ItemSelection::updateHilight(Vec2<double>, double) [28]
0.00 0.04 9217/9217 MapEditor::Renderer::updateAnimations(double) [104]
0.00 0.01 276/276 InfoOverlay3D::update(int, MapEditor::ItemType, SLADEMap*) [275]
0.00 0.01 2201/5374 MapEditor::setStatusText(std::basic_string_view<char, std::char_traits<char> >, int) [204]
0.00 0.01 250/252 MapEditContext::updateInfoOverlay() [515]
0.00 0.01 9217/9217 MapEditor::Renderer::animationsActive() const [535]
0.00 0.00 2201/2201 std::__cxx11::basic_string<fmt::v5::char_t<char [23]>::type, std::char_traits<fmt::v5::char_t<char [23]>::type>, std::allocator<fmt::v5::char_t<char [23]>::type> > fmt::v5::format<char [23], int, int, int>(char const (&) [23], int const&, int const&, int const&) [737]
0.00 0.00 4898/4898 ItemSelection::hilightedObject() const [976]
0.00 0.00 542/542 MapEditor::Renderer::animateHilightChange(MapEditor::Item const&, MapObject*) [1040]
0.00 0.00 16233/22810 ItemSelection::hilight() const [10626]
0.00 0.00 14032/20572 MapEditor::Input::mouseState() const [10661]
0.00 0.00 11418/45166 MapEditContext::overlayActive() const [10317]
0.00 0.00 7307/9409 ItemSelection::hasHilight() const [11164]
0.00 0.00 7016/9217 MapEditor::Item::operator!=(MapEditor::Item const&) const [11203]
0.00 0.00 5778/5804 MapEditor::Input::mousePosMap() const [11488]
0.00 0.00 4898/9342 MapEditor::Renderer::view() [11175]
0.00 0.00 4898/37431 MapEditor::RenderView::scale(bool) const [10389]
0.00 0.00 4402/10015 MapEditor::Renderer::renderer3D() [11116]
0.00 0.00 2450/10966 MapEditor::Item::Item(int, MapEditor::ItemType) [11020]
0.00 0.00 2201/2201 MapRenderer3D::camPosition() const [12436]
0.00 0.00 2201/2201 ItemSelection::hilightLocked() const [12435]
0.00 0.00 2201/2201 ItemSelection::setHilight(MapEditor::Item const&) [12430]
0.00 0.00 880/880 MoveObjects::update(Vec2<double>) [13344]
0.00 0.00 542/1476321 CBoolCVar::operator bool() const [9707]
-----------------------------------------------
I hope this can help to have a clearer view about what is going on.
Best regards.
TrenchBroom (an OpenGL-based wxWidgets application) had the very same issue on Linux until they migrated to Qt (it's butter smooth now). Is this even fixable while staying on wxWidgets?
I doubt it'd have anything to do with wxWidgets itself (perhaps how I'm using it though?)
Unfortunately while it'd be nice, moving to something else like Qt would take a very long time. I did have a look at how SLADE could work in Qt a while ago and it was certainly a lot nicer than wx, especially with the ability to custom theme everything (eg. dark theme in windows)
I'm on 3.2.0 and this is still happening.
I definitely encounter this too (kubuntu 21.04). Ironically, it seems this does not happen under Wine. I can't speak for everyone but it's all super smooth when running it there, although there are plenty of other problems (like it violently explodes if I try to open a directory, for instance)
Woe are we, the linux mappers...
I wish I had the skill and energy and C++ knowledge to help work this stuff out. SLADE is such a great tool.
This is the wxWidgets patch that TrenchBroom used to (mostly) resolve issues around slowdown over time on Linux: https://github.com/TrenchBroom/TrenchBroom/blob/v2019.6/patches/wxWidgets/motion_notify.patch
You need to apply this patch to the wxWidgets source code, compile wxWidgets and link it against SLADE instead of relying on system-provided wxWidgets.
It seems that the issue was fixed in wxWidgets itself in 2019, but this requires you to build against a recent enough wxWidgets version: https://trac.wxwidgets.org/ticket/18314 wxWidgets 3.1.5 should work for this.
[sigh] Yeah, I don't know what I'm doing with build processes enough to get this to work. I got it to compile at least, but it just hard-crashes as soon as I try to open any rendered panels my build, so... probably better if someone who knows what they're doing tries it.
edit: Ok, wx 3.1.5 was too much for SLADE to digest all in one go it seems, but I applied the patch to wx 3.0.5 and it seems to have compiled okay. I will play around with it a bit and report how it works. First impressions are that it's still pretty choppy and stuttery but we'll see how it goes after leaving it open a while.
edit2: Still seems okay, I guess. Although it's so jarring going back and forth between the wine and native linux versions, the native version drops so many frames and feels like it's living a painful existence, while the wine version is perfect and fluid.
@Calinou Are you sure this solves the right problem? That patch was upstreamed into wxWidgets three years ago.
Strangely it seems that the 3.1.5 version is only available from the AUR...
This is the wxWidgets patch that TrenchBroom used to (mostly) resolve issues around slowdown over time on Linux: https://github.com/TrenchBroom/TrenchBroom/blob/v2019.6/patches/wxWidgets/motion_notify.patch
You need to apply this patch to the wxWidgets source code, compile wxWidgets and link it against SLADE instead of relying on system-provided wxWidgets.
It seems that the issue was fixed in wxWidgets itself in 2019, but this requires you to build against a recent enough wxWidgets version: https://trac.wxwidgets.org/ticket/18314 wxWidgets 3.1.5 should work for this.
For what it's worth, wxWidgets seems to have stopped using trac, so the 2019 issue fix is found here now: https://github.com/wxWidgets/wxWidgets/issues/18314
Also, can confirm issue is still present on Ubuntu 22.04 for Slade 3.2.0
The version of wxWidgets installed on my system is 3.0.5, which I found by entering wx-config --version
into a terminal. Thought it was worthwhile mentioning, because 22.04 seems to be a major update, and it might have moved to a new wxWidgets version.
@inventor200 note that the version of wx you have installed is only relevant if you built slade yourself. You can see the version of wx slade was built with at the beginning of the console log in slade
Oh! My bad; that makes a lot more sense
This really sucks, should probably open a upstream bug ticket on wxwidget
My system wxWidgets is now up to 3.2.0, and this is still an issue.
perf top
now labels the mystery time-eating function as g_source_ref
, which apparently just increments a refcount, so that's not very insightful.
The earliest mention I can find of SLADE running poorly is that I mentioned it offhand on Twitter on Sep 18, 2018, though I also see #876 which is from May and also on Linux.
The last time I made heavy use of SLADE was, I think, sometime in mid-2016.
So something changed in that two-year span. But nothing obvious stands out.
I thought about bisecting, but there have been so many changes both internally and for compatibility with wx that that seems... painful.
I'm also even more confident that this can happen without ever launching the map editor, but the map editor does speed make it happen sooner.
Currently trying to throw a few tools at it — valgrind first, then maybe some GL debugging stuff.
Supposedly glib has a mechanism for logging events, which would be very helpful when the glib event loop seems to be the main symptom, but I can't get it to work.
By overriding SLADEWxApp::FilterEvent
, I have discovered that wx is firing upwards of 20 wxEVT_UPDATE_UI
/wxUpdateUIEvent
s per millisecond, although (a) SLADE never uses these itself so it's not clear why they'd be a problem for SLADE specifically, and (b) apparently the filter can run multiple times for the same event so that may not mean anything.
Disabling the "update UI" events doesn't help.
Trying to narrow it down more specifically:
- Opened SLADE to the start page, did nothing else, left it running overnight. CPU use still around 2~3%.
- Opened doom2.wad, did nothing else, waited an hour or so. CPU use unchanged.
- Clicked on
PLAYPAL
, waited a little longer. CPU use unchanged. - Opened
MAP01
in the map editor, then immediately closed it. Fifteen minutes later, CPU use is at 18%, andperf top
blames it all ong_source_ref
. Another half hour later, it's up to 28%. - Restarted SLADE, opened the map dialog, then closed it without opening the map editor. An hour later, CPU use is at 18% as before. Another hour later, unchanged.
So OGLCanvas
is certainly looking suspicious, and moreover, it's something caused by simply creating a canvas — it doesn't need to persist beyond that.