Skip to content

Commit

Permalink
[Mac] Refactored use of NSAutoreleasePool.
Browse files Browse the repository at this point in the history
- Replaced autorelease commands from NSString objects with explicit release calls.
- Drain global NSAutoreleasePool object in ProcessEvents() to be called once per frame.

TODO: This is still leaking memory, e.g. HelloTriangle/Metal leaks about 0.1 MB every 3 seconds on an Intel Mac.
  • Loading branch information
LukasBanana committed Nov 13, 2024
1 parent 05425c2 commit e3fba9b
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 34 deletions.
7 changes: 0 additions & 7 deletions examples/Cpp/ExampleBase/ExampleBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -678,14 +678,7 @@ void ExampleBase::MainLoop()
}

// Draw current frame
#ifdef LLGL_OS_MACOS
@autoreleasepool
{
DrawFrame();
}
#else
DrawFrame();
#endif

input.Reset();
}
Expand Down
3 changes: 3 additions & 0 deletions sources/Platform/MacOS/MacOSAppDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ namespace LLGL
// Allocates the NSApplicationDelegate if not already done.
void LoadNSAppDelegate();

// Releases the autorelease pool to drain all of its autoreleased objects and re-allocates the pool.
void DrainAutoreleasePool();


} // /namespace LLGL

Expand Down
21 changes: 15 additions & 6 deletions sources/Platform/MacOS/MacOSAppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -97,22 +97,31 @@ - (void)applicationWillFinishLaunching:(NSNotification *)notification
{


static bool g_appDelegateCreated = false;
static bool g_appDelegateCreated = false;
static MacOSAppDelegate* g_defaultAppDelegate = nil;
static NSAutoreleasePool* g_autoreleasePool = nil;

static void AllocDefaultNSAppDelegate()
{
/* Initialize Cocoa framework */
[[NSAutoreleasePool alloc] init];
g_autoreleasePool = [[NSAutoreleasePool alloc] init];
[NSApplication sharedApplication];

[NSApp setDelegate:(id<NSApplicationDelegate>)[
[MacOSAppDelegate alloc]
autorelease
]];
g_defaultAppDelegate = [MacOSAppDelegate alloc];
[NSApp setDelegate:g_defaultAppDelegate];

[NSApp finishLaunching];
}

void DrainAutoreleasePool()
{
if (g_autoreleasePool != nil)
{
[g_autoreleasePool release];
g_autoreleasePool = [[NSAutoreleasePool alloc] init];
}
}

void LoadNSAppDelegate()
{
if (!g_appDelegateCreated)
Expand Down
8 changes: 0 additions & 8 deletions sources/Platform/MacOS/MacOSCompatibility.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,6 @@

/* Define MacOS version specific macros */

#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
# define LLGL_MACOS_AUTORELEASEPOOL_OPEN @autoreleasepool {
# define LLGL_MACOS_AUTORELEASEPOOL_CLOSE }
#else
# define LLGL_MACOS_AUTORELEASEPOOL_OPEN NSAutoreleasePool* autoreleasePool = [[NSAutoreleasePool alloc] init];
# define LLGL_MACOS_AUTORELEASEPOOL_CLOSE [autoreleasePool release];
#endif // /MAC_OS_X_VERSION_10_7

#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12

#define LLGL_MACOS_NSWINDOWSTYLEMASK_BORDERLESS ( NSWindowStyleMaskBorderless )
Expand Down
26 changes: 13 additions & 13 deletions sources/Platform/MacOS/MacOSWindow.mm
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static bool IsFilteredNSEventType(NSEventType type)

bool Surface::ProcessEvents()
{
LLGL_MACOS_AUTORELEASEPOOL_OPEN
DrainAutoreleasePool();

/* Process NSWindow events with latest event types */
while (NSEvent* event = [NSApp nextEventMatchingMask:g_EventMaskAny untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES])
Expand All @@ -91,8 +91,6 @@ static bool IsFilteredNSEventType(NSEventType type)
[NSApp sendEvent:event];
}

LLGL_MACOS_AUTORELEASEPOOL_CLOSE

return true;
}

Expand All @@ -101,15 +99,12 @@ static bool IsFilteredNSEventType(NSEventType type)
* Window class
*/

static NSString* ToNSString(const UTF8String& s)
static NSString* ToNewNSString(const UTF8String& s)
{
return
[
[[NSString alloc]
initWithBytes: s.c_str()
length: sizeof(char)*s.size()
encoding: NSUTF8StringEncoding
] autorelease
return [[NSString alloc]
initWithBytes: s.c_str()
length: sizeof(char)*s.size()
encoding: NSUTF8StringEncoding
];
}

Expand Down Expand Up @@ -290,7 +285,9 @@ static void SetRelativeNSWindowPosition(NSWindow* wnd, const Offset2D& position,

void MacOSWindow::SetTitle(const UTF8String& title)
{
[wnd_ setTitle:ToNSString(title.c_str())];
NSString* titleNS = ToNewNSString(title.c_str());
[wnd_ setTitle:titleNS];
[titleNS release];
}

UTF8String MacOSWindow::GetTitle() const
Expand Down Expand Up @@ -438,7 +435,10 @@ static void SetRelativeNSWindowPosition(NSWindow* wnd, const Offset2D& position,
/* Set initial window properties */
[wnd setDelegate:wndDelegate_];
[wnd setAcceptsMouseMovedEvents:YES];
[wnd setTitle:ToNSString(desc.title.c_str())];

NSString* titleNS = ToNewNSString(desc.title.c_str());
[wnd setTitle:titleNS];
[titleNS release];

#if 0
/* Set window collection behavior for resize events */
Expand Down

0 comments on commit e3fba9b

Please sign in to comment.