From 756fe2e72bcce5b03a88ae1024302ecd0ec70fbc Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 18 Sep 2024 23:51:09 +0200 Subject: [PATCH 1/2] cocoa: Fix a very minor memory leak in DisplayInformation --- panda/src/cocoadisplay/cocoaGraphicsPipe.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/cocoadisplay/cocoaGraphicsPipe.mm b/panda/src/cocoadisplay/cocoaGraphicsPipe.mm index 3ad9099545..2605723a59 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsPipe.mm +++ b/panda/src/cocoadisplay/cocoaGraphicsPipe.mm @@ -160,7 +160,7 @@ load_display_information() { // Get processor information const NXArchInfo *ainfo = NXGetLocalArchInfo(); - _display_information->_cpu_brand_string = strdup(ainfo->description); + _display_information->_cpu_brand_string.assign(ainfo->description); // Get version of Mac OS X SInt32 major, minor, bugfix; From 9f493f588d02591906ba011b2802c5bdb23c2091 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 19 Sep 2024 00:21:22 +0200 Subject: [PATCH 2/2] display: Fix significant memory leak on newer macOS versions It seems the Metal-based OpenGL driver uses autorelease a lot for resources that last only a single frame, so we need to create an autorelease pool around the frame lest the resources will only get cleaned up at application exit. --- panda/src/display/graphicsEngine.cxx | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index 4fcbd323a2..a2b20b6bdb 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -62,6 +62,17 @@ #include #endif +#if defined(__APPLE__) && !defined(CPPPARSER) +#include + +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 +extern "C" { + void *objc_autoreleasePoolPush(); + void objc_autoreleasePoolPop(void *); +}; +#endif +#endif + using std::string; PT(GraphicsEngine) GraphicsEngine::_global_ptr; @@ -2550,11 +2561,20 @@ do_frame(GraphicsEngine *engine, Thread *current_thread) { PStatTimer timer(engine->_do_frame_pcollector, current_thread); LightReMutexHolder holder(_wl_lock); +#if defined(__APPLE__) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + // Enclose the entire frame in an autorelease pool. + void *pool = objc_autoreleasePoolPush(); +#endif + engine->cull_to_bins(_cull, current_thread); engine->cull_and_draw_together(_cdraw, current_thread); engine->draw_bins(_draw, current_thread); engine->process_events(_window, current_thread); +#if defined(__APPLE__) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + objc_autoreleasePoolPop(pool); +#endif + // If any GSG's on the list have no more outstanding pointers, clean them // up. (We are in the draw thread for all of these GSG's.) if (any_done_gsgs()) { @@ -2586,10 +2606,18 @@ void GraphicsEngine::WindowRenderer:: do_windows(GraphicsEngine *engine, Thread *current_thread) { LightReMutexHolder holder(_wl_lock); +#if defined(__APPLE__) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + void *pool = objc_autoreleasePoolPush(); +#endif + engine->process_events(_window, current_thread); engine->make_contexts(_cdraw, current_thread); engine->make_contexts(_draw, current_thread); + +#if defined(__APPLE__) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + objc_autoreleasePoolPop(pool); +#endif } /**