Skip to content

Commit e415a03

Browse files
committed
resolver lifecycle fix
1 parent 049dfe5 commit e415a03

3 files changed

Lines changed: 19 additions & 6 deletions

File tree

src/api/include/projectM-4/core.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ extern "C" {
3838
* If this function returns NULL, in most cases the OpenGL context is not initialized, not made
3939
* current or insufficient to render projectM visuals.
4040
*
41-
* Note: The OpenGL resolver is initialized on the first invocation of either projectm_create() or projectm_create_with_opengl_load_proc().
42-
* All projectM instances created will use the same resolver.
41+
* Note: The OpenGL resolver is initialized on the first call to either projectm_create() or projectm_create_with_opengl_load_proc().
42+
* All projectM instances share the same resolver, and subsequent calls ignore the provided load_proc.
43+
* The resolver instance is tied to the lifecycle of the created projectM instances.
44+
* It is released when the last projectM instance is released, and can be reinitialized.
4345
*
4446
* @return A projectM handle for the newly created instance that must be used in subsequent API calls.
4547
* NULL if the instance could not be created successfully.
@@ -54,8 +56,10 @@ PROJECTM_EXPORT projectm_handle projectm_create();
5456
* If this function returns NULL, in most cases the OpenGL context is not initialized, not made
5557
* current or insufficient to render projectM visuals.
5658
*
57-
* Note: The OpenGL resolver is initialized on the first invocation of either projectm_create() or projectm_create_with_opengl_load_proc().
58-
* All projectM instances created will use the same resolver and subsequent calls will ignore the given load_proc.
59+
* Note: The OpenGL resolver is initialized on the first call to either projectm_create() or projectm_create_with_opengl_load_proc().
60+
* All projectM instances share the same resolver, and subsequent calls ignore the provided load_proc.
61+
* The resolver instance is tied to the lifecycle of the created projectM instances.
62+
* It is released when the last projectM instance is released, and can be reinitialized.
5963
*
6064
* @return A projectM handle for the newly created instance that must be used in subsequent API calls.
6165
* NULL if the instance could not be created successfully.

src/libprojectM/ProjectM.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ class PROJECTM_EXPORT ProjectM
296296
bool m_presetLocked{false}; //!< If true, the preset change event will not be sent.
297297
bool m_presetChangeNotified{false}; //!< Stores whether the user has been notified that projectM wants to switch the preset.
298298

299-
std::shared_ptr<Renderer::Platform::GLResolver> m_glResolver; //!< Function resolver for accessing GL backend.
299+
std::shared_ptr<Renderer::Platform::GLResolver> m_glResolver; //!< Function resolver for accessing GL backend. Stored for keeping ref count, may be null.
300300
std::unique_ptr<PresetFactoryManager> m_presetFactoryManager; //!< Provides access to all available preset factories.
301301

302302
Audio::PCM m_audioStorage; //!< Audio data buffer and analyzer instance.

src/libprojectM/Renderer/PlatformGLResolver.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,16 @@ GLResolver::~GLResolver()
2828

2929
auto GLResolver::Instance() -> std::shared_ptr<GLResolver>
3030
{
31-
static const std::shared_ptr<GLResolver> instance = std::make_shared<GLResolver>();
31+
// observe resolver instance with a weak pointer
32+
// so that it is shared, but released once the last
33+
// client shared_ptr is released
34+
static std::weak_ptr<GLResolver> sharedInstance;
35+
auto instance = sharedInstance.lock();
36+
if (!instance)
37+
{
38+
instance = std::make_shared<GLResolver>();
39+
sharedInstance = instance;
40+
}
3241
return instance;
3342
}
3443

0 commit comments

Comments
 (0)