SLADE icon indicating copy to clipboard operation
SLADE copied to clipboard

SLADE performance gradually degrades until it's unusable

Open eevee opened this issue 6 years ago • 26 comments

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.

eevee avatar Jan 05 '19 20:01 eevee

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.

zgramps avatar Jan 05 '19 21:01 zgramps

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.

eevee avatar Jan 05 '19 22:01 eevee

Haven't noticed this problem on Windows, so it's probably Linux-specific.

Gaerzi avatar Jan 07 '19 18:01 Gaerzi

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

sirjuddington avatar Jan 07 '19 22:01 sirjuddington

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.

Gaerzi avatar Jan 08 '19 10:01 Gaerzi

Would early returning from Drawing::drawText be enough?

eevee avatar Jan 08 '19 19:01 eevee

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)

zgramps avatar Jan 08 '19 21:01 zgramps

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. :)

eevee avatar Jan 09 '19 21:01 eevee

Ahhhh I knew I wasn't alone on this. Good catch.

OrdinaryMagician avatar Jan 16 '19 09:01 OrdinaryMagician

Still happening on master, even just from leaving it open with a single archive loaded. :( And still no idea why.

eevee avatar Dec 03 '19 15:12 eevee

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

sirjuddington avatar Dec 03 '19 21:12 sirjuddington

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.

ghost avatar Mar 29 '20 13:03 ghost

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.

ghost avatar Apr 02 '20 21:04 ghost

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?

Calinou avatar May 26 '20 19:05 Calinou

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)

sirjuddington avatar May 26 '20 23:05 sirjuddington

I'm on 3.2.0 and this is still happening.

flarn2006 avatar May 09 '21 22:05 flarn2006

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.

novaplusplus avatar Sep 15 '21 18:09 novaplusplus

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.

Calinou avatar Sep 15 '21 18:09 Calinou

[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.

novaplusplus avatar Sep 15 '21 22:09 novaplusplus

@Calinou Are you sure this solves the right problem? That patch was upstreamed into wxWidgets three years ago.

eevee avatar Sep 16 '21 05:09 eevee

Strangely it seems that the 3.1.5 version is only available from the AUR...

OrdinaryMagician avatar Sep 16 '21 08:09 OrdinaryMagician

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

inventor200 avatar May 03 '22 13:05 inventor200

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 avatar May 03 '22 13:05 inventor200

@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

sirjuddington avatar May 04 '22 01:05 sirjuddington

Oh! My bad; that makes a lot more sense

inventor200 avatar May 04 '22 04:05 inventor200

This really sucks, should probably open a upstream bug ticket on wxwidget

FlykeSpice avatar May 13 '22 19:05 FlykeSpice

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.

eevee avatar Nov 16 '22 20:11 eevee

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.

eevee avatar Nov 17 '22 02:11 eevee

By overriding SLADEWxApp::FilterEvent, I have discovered that wx is firing upwards of 20 wxEVT_UPDATE_UI/wxUpdateUIEvents 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.

eevee avatar Nov 17 '22 03:11 eevee

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%, and perf top blames it all on g_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.

eevee avatar Nov 17 '22 22:11 eevee