File: ShaderHandler.cpp

package info (click to toggle)
spring 105.0.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 108,860 kB
  • sloc: cpp: 467,785; ansic: 302,607; python: 12,925; java: 12,201; awk: 5,889; sh: 2,371; xml: 655; perl: 405; php: 276; objc: 194; makefile: 75; sed: 2
file content (118 lines) | stat: -rw-r--r-- 3,042 bytes parent folder | download | duplicates (3)
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
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#include "Rendering/Shaders/ShaderHandler.h"
#include "Rendering/Shaders/Shader.h"
#include "System/Log/ILog.h"

#include <cassert>


CShaderHandler* CShaderHandler::GetInstance()
{
	static CShaderHandler instance;
	return &instance;
}


void CShaderHandler::ClearShaders(bool persistent)
{
	for (auto& p: programObjects[persistent]) {
		// release by poMap (not poClass) to avoid erase-while-iterating pattern
		ReleaseProgramObjectsMap(p.second);
	}

	programObjects[persistent].clear();
}


void CShaderHandler::ReloadShaders(bool persistent)
{
	for (const auto& p1: programObjects[persistent]) {
		for (const auto& p2: p1.second) {
			p2.second->Reload(true, false);
		}
	}
}


void CShaderHandler::InsertExtProgramObject(const char* name, Shader::IProgramObject* prog)
{
	assert(name[0] != 0);

	if (GetExtProgramObject(name) != nullptr)
		return;

	assert(GetExtShaderSources(name) == nullptr);

	// for RenderDataBuffer shaders, collision freedom is
	// guaranteed at compile-time by GetShaderName switch
	const unsigned int hash = hashString(name);

	extProgramObjects.insert(hash, prog);
	extShaderSources.insert(hash, {});

	// the attached shader objects may go away later, so make
	// copies of their source strings while those still exist
	for (const Shader::IShaderObject* shader: prog->GetShaderObjs()) {
		extShaderSources[hash][ GL::ShaderTypeToEnum(shader->GetType()) ] = shader->GetSrc(false);
	}
}


bool CShaderHandler::ReleaseProgramObjects(const std::string& poClass, bool persistent)
{
	ProgramTable& pTable = programObjects[persistent];

	if (pTable.find(poClass) == pTable.end())
		return false;

	ReleaseProgramObjectsMap(pTable[poClass]);

	pTable.erase(poClass);
	return true;
}

void CShaderHandler::ReleaseProgramObjectsMap(ProgramObjMap& poMap)
{
	for (const auto& item: poMap) {
		Shader::IProgramObject* po = item.second;

		// free the program object and its attachments
		if (po == Shader::nullProgramObject)
			continue;

		// erases
		shaderCache.Find(po->GetHash());
		po->Release();
		delete po;
	}

	poMap.clear();
}


Shader::IProgramObject* CShaderHandler::CreateProgramObject(const std::string& poClass, const std::string& poName, bool persistent)
{
	assert(!poClass.empty());
	assert(!poName.empty());

	ProgramTable& pTable = programObjects[persistent];

	if (pTable.find(poClass) == pTable.end())
		pTable[poClass] = ProgramObjMap();

	if (pTable[poClass].find(poName) == pTable[poClass].end())
		return (pTable[poClass][poName] = new Shader::GLSLProgramObject(poName));

	// do not allow multiple references to the same shader
	LOG_L(L_WARNING, "[SH::%s] program-object \"%s\" in class \"%s\" already exists", __func__, poName.c_str(), poClass.c_str());
	return Shader::nullProgramObject;
}


Shader::IShaderObject* CShaderHandler::CreateShaderObject(const std::string& soName, const std::string& soDefs, int soType)
{
	assert(!soName.empty());
	return (new Shader::GLSLShaderObject(soType, soName, soDefs));
}