Created
November 26, 2016 18:45
-
-
Save attilaz/d75fc7d4ab75388a42720f97a7075c81 to your computer and use it in GitHub Desktop.
metal transient object lifetime
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From metal documentation: | |
"Command buffer and command encoder objects are transient and designed for a single use. | |
They are very inexpensive to allocate and deallocate, so their creation methods return autoreleased objects." | |
https://developer.apple.com/library/content/documentation/Miscellaneous/Conceptual/MetalProgrammingGuide/Cmd-Submiss/Cmd-Submiss.html | |
Autorelease example: | |
NSAutoreleasePool* autoreleasePool = [[NSAutoreleasePool alloc] init]; | |
//c is an autoreleased object | |
SampleClass* c = [[SampleClass alloc] init];//refcount is 1 | |
[c autorelease]; //refcount is 1 (1 for pool) | |
[autoreleasePool release]; //pool is released it calls release on every object it is added to. | |
//c's refcount will be 0, so it will be deallocated | |
Autorelease example 2: | |
NSAutoreleasePool* autoreleasePool = [[NSAutoreleasePool alloc] init]; | |
SampleClass* c = [[SampleClass alloc] init];//refcount is 1 | |
[c retain]; //refcount is 2 | |
[c autorelease]; //refcount is 2 (1 for pool) | |
[autoreleasePool release]; //when pool is released it calls release on every object it is added to. | |
//c's refcount will be 1, so it won't be deallocated | |
[c release]; //c's refcount will be 0, it is dealloced | |
In the examples for iOS there is an autoreleasepool now: | |
https://github.com/bkaradzic/bgfx/blob/master/examples/common/entry/entry_ios.mm#L366 | |
but there is no autoreleasepool on OSX. | |
A simple thing like this leaks on OSX but works perfectly on iOS now: | |
SampleClass* c = [[SampleClass alloc] init];//refcount is 1 | |
[c autorelease]; //refcount is 1 (1 for pool) | |
So a "m_commandBuffer = m_commandQueue.commandBuffer();" will release the object when the autoreleasepool is finished. | |
But on OSX it won't be released. | |
On iOS the autoreleasepool is finished at the end of the frame. This causes a problem when flipping is at the beginning of | |
the frame (https://github.com/bkaradzic/bgfx/blob/master/src/bgfx.cpp#L1580) because when the flip command is called | |
every transient object would be already deallocated. | |
frameX: | |
autoreleasepool begin | |
... | |
setRenderTarget(Drawable_for_frameX) | |
... | |
autoreleasepool end //Drawable_for_frameX is released here | |
frameX+1: | |
autoreleasepool begin | |
... | |
presentDrawable(Drawable_for_frameX) //error | |
... | |
autoreleasebool end | |
So we have to use manual refcount handling because of these like this | |
(https://github.com/bkaradzic/bgfx/blob/master/src/renderer_mtl.mm#L820). | |
The recent memleak is because even rendercommander encoders are transient and leaked on OSX. | |
I think we should use a method that works similarly on iOS and OSX to avoid these: | |
https://github.com/bkaradzic/bgfx/commit/dbe4c52d8f56648ee5d5d1144d19accbb4efe8c3 | |
https://github.com/bkaradzic/bgfx/commit/413972736fc60a61e1346378f2d91422546bd111#diff-816a76ffbf9c1e03ccfcc65d248f8369R1735 | |
"It is highly advisable to contain your rendering loop within an autorelease pool block to avoid possible deadlock | |
situations with multiple drawables." | |
https://developer.apple.com/library/content/documentation/3DDrawing/Conceptual/MTLBestPracticesGuide/Drawables.html | |
If we use manual release of objects it will be error-prone because on iOS there is always an autoreleasepool and if we | |
skip a manual retain/release it will work on fine on iOS and crash/leak on OSX. | |
So I think we should add an autoreleasepool in OSX too. | |
Without the need the ability to flip at the beginning of the frame we could get rid of lots of | |
manual retains/releases and use simply an autorelease pool. I don't think it is worth to keep this ability. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment