Skip to content

Commit a2e9a91

Browse files
committed
Add a global shader cache
1 parent 1b7c7c8 commit a2e9a91

File tree

6 files changed

+110
-5
lines changed

6 files changed

+110
-5
lines changed

src/libprojectM/ProjectM.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <Renderer/CopyTexture.hpp>
3131
#include <Renderer/PresetTransition.hpp>
3232
#include <Renderer/TextureManager.hpp>
33+
#include <Renderer/ShaderCache.hpp>
3334
#include <Renderer/TransitionShaderManager.hpp>
3435

3536
namespace libprojectM {
@@ -194,6 +195,7 @@ void ProjectM::Initialize()
194195
/** Initialise per-pixel matrix calculations */
195196
/** We need to initialise this before the builtin param db otherwise bass/mid etc won't bind correctly */
196197
m_textureManager = std::make_unique<Renderer::TextureManager>(m_textureSearchPaths);
198+
m_shaderCache = std::make_unique<Renderer::ShaderCache>();
197199

198200
m_transitionShaderManager = std::make_unique<Renderer::TransitionShaderManager>();
199201

@@ -452,6 +454,7 @@ auto ProjectM::GetRenderContext() -> Renderer::RenderContext
452454
ctx.perPixelMeshX = static_cast<int>(m_meshX);
453455
ctx.perPixelMeshY = static_cast<int>(m_meshY);
454456
ctx.textureManager = m_textureManager.get();
457+
ctx.shaderCache = m_shaderCache.get();
455458

456459
return ctx;
457460
}

src/libprojectM/ProjectM.hpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class CopyTexture;
3737
class PresetTransition;
3838
class Renderer;
3939
class TextureManager;
40+
class ShaderCache;
4041
class TransitionShaderManager;
4142
} // namespace Renderer
4243

@@ -200,11 +201,11 @@ class PROJECTM_EXPORT ProjectM
200201

201202
auto GetRenderContext() -> Renderer::RenderContext;
202203

203-
uint32_t m_meshX{32}; //!< Per-point mesh horizontal resolution.
204-
uint32_t m_meshY{24}; //!< Per-point mesh vertical resolution.
205-
uint32_t m_targetFps{35}; //!< Target frames per second.
206-
uint32_t m_windowWidth{0}; //!< EvaluateFrameData window width. If 0, nothing is rendered.
207-
uint32_t m_windowHeight{0}; //!< EvaluateFrameData window height. If 0, nothing is rendered.
204+
uint32_t m_meshX{32}; //!< Per-point mesh horizontal resolution.
205+
uint32_t m_meshY{24}; //!< Per-point mesh vertical resolution.
206+
uint32_t m_targetFps{35}; //!< Target frames per second.
207+
uint32_t m_windowWidth{0}; //!< EvaluateFrameData window width. If 0, nothing is rendered.
208+
uint32_t m_windowHeight{0}; //!< EvaluateFrameData window height. If 0, nothing is rendered.
208209
double m_presetDuration{30.0}; //!< Preset duration in seconds.
209210
double m_softCutDuration{3.0}; //!< Soft cut transition time.
210211
double m_hardCutDuration{20.0}; //!< Time after which a hard cut can happen at the earliest.
@@ -227,6 +228,7 @@ class PROJECTM_EXPORT ProjectM
227228

228229
Audio::PCM m_audioStorage; //!< Audio data buffer and analyzer instance.
229230
std::unique_ptr<Renderer::TextureManager> m_textureManager; //!< The texture manager.
231+
std::unique_ptr<Renderer::ShaderCache> m_shaderCache; //!< The global shader cache.
230232
std::unique_ptr<Renderer::TransitionShaderManager> m_transitionShaderManager; //!< The transition shader manager.
231233
std::unique_ptr<Renderer::CopyTexture> m_textureCopier; //!< Class that copies textures 1:1 to another texture or framebuffer.
232234
std::unique_ptr<Preset> m_activePreset; //!< Currently loaded preset.

src/libprojectM/Renderer/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ add_library(Renderer OBJECT
4949
Sampler.hpp
5050
Shader.cpp
5151
Shader.hpp
52+
ShaderCache.cpp
53+
ShaderCache.hpp
5254
Texture.cpp
5355
Texture.hpp
5456
TextureAttachment.cpp

src/libprojectM/Renderer/RenderContext.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
namespace libprojectM {
88
namespace Renderer {
99

10+
class ShaderCache;
1011
class TextureManager;
1112

1213
/**
@@ -30,6 +31,7 @@ class RenderContext
3031
int perPixelMeshY{48}; //!< Per-pixel/per-vertex mesh Y resolution.
3132

3233
TextureManager* textureManager{nullptr}; //!< Holds all loaded textures for shader access.
34+
ShaderCache* shaderCache{nullptr}; //!< The shader chace of this projectM instance.
3335
};
3436

3537
} // namespace Renderer
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include "ShaderCache.hpp"
2+
3+
#include <utility>
4+
5+
namespace libprojectM {
6+
namespace Renderer {
7+
8+
void ShaderCache::Insert(const std::string& key, const std::shared_ptr<Shader>& shader)
9+
{
10+
m_cachedShaders.emplace(key, shader);
11+
}
12+
13+
void ShaderCache::Insert(const std::string& key, std::shared_ptr<Shader>&& shader)
14+
{
15+
m_cachedShaders.emplace(key, std::move(shader));
16+
}
17+
18+
void ShaderCache::Remove(const std::string& key)
19+
{
20+
m_cachedShaders.erase(key);
21+
}
22+
23+
auto ShaderCache::Get(const std::string& key) const -> std::shared_ptr<Shader>
24+
{
25+
if (m_cachedShaders.find(key) != m_cachedShaders.end())
26+
{
27+
return m_cachedShaders.at(key);
28+
}
29+
30+
return {};
31+
}
32+
33+
} // namespace Renderer
34+
} // namespace libprojectM
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#pragma once
2+
3+
#include "Renderer/Shader.hpp"
4+
5+
#include <map>
6+
#include <memory>
7+
#include <string>
8+
9+
namespace libprojectM {
10+
namespace Renderer {
11+
12+
/**
13+
* @brief Instance shader cache.
14+
*
15+
* Used to store shaders which only need to be compiled once per projectM instance.
16+
* Removes the need for the previously used static shader provider, and reduces
17+
* shader recompilation times.
18+
*
19+
* Shaders are accessed by arbitrary strings as keys.
20+
*
21+
* All cached shader programs will be properly deleted when the projectM instance is destroyed.
22+
* Classes storing a reference to a cached shader should ideally use an std::weak_ptr to do so.
23+
*/
24+
class ShaderCache
25+
{
26+
public:
27+
/**
28+
* @brief Adds a new shader to the cache.
29+
* If the shader already exists, the existing cache entry it NOT replaced.
30+
* @param key The key to store the shader with.
31+
* @param shader A shared pointer to the shader program to be cached.
32+
*/
33+
void Insert(const std::string& key, const std::shared_ptr<Shader>& shader);
34+
35+
/**
36+
* @brief Adds a new shader to the cache.
37+
* If the shader already exists, the existing cache entry it NOT replaced.
38+
* @param key The key to store the shader with.
39+
* @param shader A shared pointer to the shader program to be cached.
40+
*/
41+
void Insert(const std::string& key, std::shared_ptr<Shader>&& shader);
42+
43+
/**
44+
* @brief Removes a shader from the cache.
45+
* If the key does not exist in the cache, this function will not do anything.
46+
* @param key The key of the sahder to be removed.
47+
*/
48+
void Remove(const std::string& key);
49+
50+
/**
51+
* @brief Returns a cached shader.
52+
* @param key the key of the cached shader to be returned.
53+
* @return A shared pointer to the cached shader program, or nullptr if the key wasn't found.
54+
*/
55+
auto Get(const std::string& key) const -> std::shared_ptr<Shader>;
56+
57+
private:
58+
std::map<std::string, std::shared_ptr<Shader>> m_cachedShaders;
59+
};
60+
61+
} // namespace Renderer
62+
} // namespace libprojectM

0 commit comments

Comments
 (0)