Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

Diff Revisions 838 vs 839 for /trunk/Source Code/Platform/Video/Shaders/ShaderProgram.cpp

Diff revisions: vs.
  @@ -7,7 +7,33 @@
7 7 #include "Rendering/Lighting/ShadowMapping/Headers/ShadowMap.h"
8 8 #include "Platform/Video/Headers/GFXDevice.h"
9 9
10 + #include "simplefilewatcher/includes/FileWatcher.h"
11 +
10 12 namespace Divide {
13 + namespace {
14 + class UpdateListener : public FW::FileWatchListener
15 + {
16 + public:
17 + UpdateListener()
18 + {
19 + }
20 +
21 + void handleFileAction(FW::WatchID watchid, const FW::String& dir, const FW::String& filename, FW::Action action)
22 + {
23 + switch (action)
24 + {
25 + case FW::Actions::Add: break;
26 + case FW::Actions::Delete: break;
27 + case FW::Actions::Modified:
28 + ShaderProgram::onAtomChange(filename.c_str());
29 + break;
30 +
31 + default:
32 + DIVIDE_UNEXPECTED_CALL("Unknown file event!");
33 + }
34 + };
35 + } s_fileWatcherListener;
36 + };
11 37
12 38 ShaderProgram_ptr ShaderProgram::_imShader;
13 39 ShaderProgram_ptr ShaderProgram::_nullShader;
  @@ -16,6 +42,8 @@
16 42 ShaderProgram::ShaderProgramMap ShaderProgram::_shaderPrograms;
17 43 SharedLock ShaderProgram::_programLock;
18 44
45 + std::unique_ptr<FW::FileWatcher> ShaderProgram::s_shaderFileWatcher;
46 +
19 47 ShaderProgram::ShaderProgram(GFXDevice& context, const stringImpl& name, const stringImpl& resourceName, const stringImpl& resourceLocation, bool asyncLoad)
20 48 : Resource(ResourceType::GPU_OBJECT, name, resourceName, resourceLocation),
21 49 GraphicsResource(context, getGUID()),
  @@ -33,6 +61,7 @@
33 61
34 62 bool ShaderProgram::load() {
35 63 registerShaderProgram(getName(), shared_from_this());
64 +
36 65 return Resource::load();
37 66 }
38 67
  @@ -87,7 +116,7 @@
87 116 if (getState() != ResourceState::RES_LOADED) {
88 117 return true;
89 118 }
90 -
119 + _usedAtoms.clear();
91 120 // Remember bind state
92 121 bool wasBound = isBound();
93 122 if (wasBound) {
  @@ -103,6 +132,10 @@
103 132 return state;
104 133 }
105 134
135 + void ShaderProgram::registerAtomFile(const stringImpl& atomFile) {
136 + _usedAtoms.push_back(atomFile);
137 + }
138 +
106 139 //================================ static methods ========================================
107 140 void ShaderProgram::idle() {
108 141 // If we don't have any shaders queued for recompilation, return early
  @@ -113,6 +146,8 @@
113 146 }
114 147 _recompileQueue.pop();
115 148 }
149 +
150 + s_shaderFileWatcher->update();
116 151 }
117 152
118 153 /// Calling this will force a recompilation of all shader stages for the program
  @@ -140,8 +175,7 @@
140 175 return state;
141 176 }
142 177
143 - /// Open the file found at 'location' matching 'atomName' and return it's source
144 - /// code
178 + /// Open the file found at 'location' matching 'atomName' and return it's source code
145 179 const stringImpl& ShaderProgram::shaderFileRead(const stringImpl& atomName, const stringImpl& location) {
146 180 U64 atomNameHash = _ID_RT(atomName);
147 181 // See if the atom was previously loaded and still in cache
  @@ -187,9 +221,11 @@
187 221 stringImpl variant = atomName;
188 222 if (Config::Build::IS_DEBUG_BUILD) {
189 223 variant.append(".debug");
190 - } else if (Config::Build::IS_PROFILE_BUILD) {
224 + }
225 + else if (Config::Build::IS_PROFILE_BUILD) {
191 226 variant.append(".profile");
192 - } else {
227 + }
228 + else {
193 229 variant.append(".release");
194 230 }
195 231
  @@ -197,6 +233,14 @@
197 233 }
198 234
199 235 void ShaderProgram::onStartup(ResourceCache& parentCache) {
236 + s_shaderFileWatcher = std::make_unique<FW::FileWatcher>();
237 +
238 + vectorImpl<stringImpl> atomLocations = getAllAtomLocations();
239 + for (const stringImpl& loc : atomLocations) {
240 + createDirectories(loc.c_str());
241 + s_shaderFileWatcher->addWatch(loc, &s_fileWatcherListener);
242 + }
243 +
200 244 // Create an immediate mode rendering shader that simulates the fixed function pipeline
201 245 ResourceDescriptor immediateModeShader("ImmediateModeEmulation");
202 246 immediateModeShader.setThreadedLoading(false);
  @@ -214,9 +258,11 @@
214 258 _shaderPrograms.clear();
215 259 _nullShader.reset();
216 260 _imShader.reset();
217 - while(!_recompileQueue.empty()) {
261 + while (!_recompileQueue.empty()) {
218 262 _recompileQueue.pop();
219 263 }
264 +
265 + s_shaderFileWatcher.reset();
220 266 }
221 267
222 268 bool ShaderProgram::updateAll(const U64 deltaTime) {
  @@ -268,4 +314,71 @@
268 314 }
269 315 }
270 316
317 + void ShaderProgram::onAtomChange(const stringImpl& atomName) {
318 + //Get list of shader programs that use the atom and rebuild all shaders in list;
319 + for (ShaderProgramMap::value_type& it : _shaderPrograms) {
320 + for (const stringImpl& atom : it.second->_usedAtoms) {
321 + if (atom.compare(atomName) == 0) {
322 + _recompileQueue.push(it.second);
323 + break;
324 + }
325 + }
326 + }
327 + }
328 +
329 + vectorImpl<stringImpl> ShaderProgram::getAllAtomLocations() {
330 + static vectorImpl<stringImpl> atomLocations;
331 + if (atomLocations.empty()) {
332 + // General
333 + atomLocations.emplace_back(Paths::g_assetsLocation +
334 + Paths::g_shadersLocation);
335 + // GLSL
336 + atomLocations.emplace_back(Paths::g_assetsLocation +
337 + Paths::g_shadersLocation +
338 + Paths::Shaders::GLSL::g_parentShaderLoc);
339 +
340 + atomLocations.emplace_back(Paths::g_assetsLocation +
341 + Paths::g_shadersLocation +
342 + Paths::Shaders::GLSL::g_parentShaderLoc +
343 + Paths::Shaders::GLSL::g_comnAtomLoc);
344 +
345 + atomLocations.emplace_back(Paths::g_assetsLocation +
346 + Paths::g_shadersLocation +
347 + Paths::Shaders::GLSL::g_parentShaderLoc +
348 + Paths::Shaders::GLSL::g_compAtomLoc);
349 +
350 + atomLocations.emplace_back(Paths::g_assetsLocation +
351 + Paths::g_shadersLocation +
352 + Paths::Shaders::GLSL::g_parentShaderLoc +
353 + Paths::Shaders::GLSL::g_fragAtomLoc);
354 +
355 + atomLocations.emplace_back(Paths::g_assetsLocation +
356 + Paths::g_shadersLocation +
357 + Paths::Shaders::GLSL::g_parentShaderLoc +
358 + Paths::Shaders::GLSL::g_geomAtomLoc);
359 +
360 + atomLocations.emplace_back(Paths::g_assetsLocation +
361 + Paths::g_shadersLocation +
362 + Paths::Shaders::GLSL::g_parentShaderLoc +
363 + Paths::Shaders::GLSL::g_tescAtomLoc);
364 +
365 + atomLocations.emplace_back(Paths::g_assetsLocation +
366 + Paths::g_shadersLocation +
367 + Paths::Shaders::GLSL::g_parentShaderLoc +
368 + Paths::Shaders::GLSL::g_teseAtomLoc);
369 +
370 + atomLocations.emplace_back(Paths::g_assetsLocation +
371 + Paths::g_shadersLocation +
372 + Paths::Shaders::GLSL::g_parentShaderLoc +
373 + Paths::Shaders::GLSL::g_vertAtomLoc);
374 + // HLSL
375 + atomLocations.emplace_back(Paths::g_assetsLocation +
376 + Paths::g_shadersLocation +
377 + Paths::Shaders::HLSL::g_parentShaderLoc);
378 +
379 + }
380 +
381 + return atomLocations;
382 + }
383 +
271 384 };