File: ShaderManager.h

package info (click to toggle)
0ad 0.0.26-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 130,460 kB
  • sloc: cpp: 261,824; ansic: 198,392; javascript: 19,067; python: 14,557; sh: 7,629; perl: 4,072; xml: 849; makefile: 741; java: 533; ruby: 229; php: 190; pascal: 30; sql: 21; tcl: 4
file content (135 lines) | stat: -rw-r--r-- 4,343 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* Copyright (C) 2022 Wildfire Games.
 * This file is part of 0 A.D.
 *
 * 0 A.D. is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * 0 A.D. is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef INCLUDED_SHADERMANAGER
#define INCLUDED_SHADERMANAGER

#include "graphics/ShaderDefines.h"
#include "graphics/ShaderProgram.h"
#include "graphics/ShaderTechnique.h"

#include <memory>
#include <set>
#include <unordered_map>

/**
 * Shader manager: loads and caches shader programs.
 *
 * For a high-level overview of shaders and materials, see
 * http://trac.wildfiregames.com/wiki/MaterialSystem
 */
class CShaderManager
{
public:
	CShaderManager();
	~CShaderManager();

	/**
	 * Load a shader effect.
	 * Effects can be implemented via many techniques; this returns the best usable technique.
	 * @param name name of effect XML specification (file is loaded from shaders/effects/${name}.xml)
	 * @param defines key/value set of preprocessor definitions
	 * @return loaded technique, or empty technique on error
	 */
	CShaderTechniquePtr LoadEffect(CStrIntern name, const CShaderDefines& defines);

	/**
	 * Load a shader effect, with default system defines (from CRenderer::GetSystemShaderDefines).
	 */
	CShaderTechniquePtr LoadEffect(CStrIntern name);

	/**
	 * Returns the number of shader effects that are currently loaded.
	 */
	size_t GetNumEffectsLoaded() const;

private:
	struct CacheKey
	{
		std::string name;
		CShaderDefines defines;

		bool operator<(const CacheKey& k) const
		{
			if (name < k.name) return true;
			if (k.name < name) return false;
			return defines < k.defines;
		}
	};

	// A CShaderProgram contains expensive GL state, so we ought to cache it.
	// The compiled state depends solely on the filename and list of defines,
	// so we store that in CacheKey.
	// TODO: is this cache useful when we already have an effect cache?
	std::map<CacheKey, CShaderProgramPtr> m_ProgramCache;

	/**
	 * Key for effect cache lookups.
	 * This stores two separate CShaderDefines because the renderer typically
	 * has one set from the rendering context and one set from the material;
	 * by handling both separately here, we avoid the cost of having to merge
	 * the two sets into a single one before doing the cache lookup.
	 */
	struct EffectCacheKey
	{
		CStrIntern name;
		CShaderDefines defines;

		bool operator==(const EffectCacheKey& b) const;
	};

	struct EffectCacheKeyHash
	{
		size_t operator()(const EffectCacheKey& key) const;
	};

	using EffectCacheMap = std::unordered_map<EffectCacheKey, CShaderTechniquePtr, EffectCacheKeyHash>;
	EffectCacheMap m_EffectCache;

	// Store the set of shaders that need to be reloaded when the given file is modified
	template<typename T>
	using HotloadFilesMap = std::unordered_map<
		VfsPath,
		std::set<std::weak_ptr<T>, std::owner_less<std::weak_ptr<T>>>>;
	HotloadFilesMap<CShaderTechnique> m_HotloadTechniques;
	HotloadFilesMap<CShaderProgram> m_HotloadPrograms;

	/**
	 * Load a shader program.
	 * @param name name of shader XML specification (file is loaded from shaders/${name}.xml)
	 * @param defines key/value set of preprocessor definitions
	 * @return loaded program, or null pointer on error
	 */
	CShaderProgramPtr LoadProgram(const CStr& name, const CShaderDefines& defines);

	bool LoadTechnique(CShaderTechniquePtr& tech);

	static Status ReloadChangedFileCB(void* param, const VfsPath& path);
	Status ReloadChangedFile(const VfsPath& path);

	/**
	 * Associates the file with the technique to be reloaded if the file has changed.
	 */
	void AddTechniqueFileDependency(const CShaderTechniquePtr& technique, const VfsPath& path);

	/**
	 * Associates the file with the program to be reloaded if the file has changed.
	 */
	void AddProgramFileDependency(const CShaderProgramPtr& program, const VfsPath& path);
};

#endif // INCLUDED_SHADERMANAGER