Skip to content

Commit b2783e5

Browse files
authored
Merge pull request #414 from fughilli/fix_shader_compilation_failure
Add mitigation for shader compilation failure
2 parents 4eed6eb + 8931bd4 commit b2783e5

File tree

3 files changed

+83
-56
lines changed

3 files changed

+83
-56
lines changed

src/libprojectM/Renderer/ShaderEngine.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,14 +1239,22 @@ GLuint ShaderEngine::CompileShaderProgram(const std::string & VertexShaderCode,
12391239
char const * VertexSourcePointer = VertexShaderCode.c_str();
12401240
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
12411241
glCompileShader(VertexShaderID);
1242-
checkCompileStatus(VertexShaderID, "Vertex: " + shaderTypeString);
1242+
if(!checkCompileStatus(VertexShaderID, "Vertex: " + shaderTypeString)) {
1243+
glDeleteShader(VertexShaderID);
1244+
glDeleteShader(FragmentShaderID);
1245+
return GL_FALSE;
1246+
}
12431247

12441248

12451249
// Compile Fragment Shader
12461250
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
12471251
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
12481252
glCompileShader(FragmentShaderID);
1249-
checkCompileStatus(FragmentShaderID, "Fragment: " + shaderTypeString);
1253+
if(!checkCompileStatus(FragmentShaderID, "Fragment: " + shaderTypeString)) {
1254+
glDeleteShader(VertexShaderID);
1255+
glDeleteShader(FragmentShaderID);
1256+
return GL_FALSE;
1257+
}
12501258

12511259

12521260
// Link the program

src/libprojectM/projectM.cpp

100755100644
Lines changed: 71 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ pthread_mutex_t preset_mutex;
6767
#endif
6868
#endif
6969

70+
namespace {
71+
constexpr int kMaxSwitchRetries = 10;
72+
}
73+
7074
projectM::~projectM()
7175
{
7276
#ifdef USE_THREADS
@@ -779,7 +783,9 @@ void projectM::selectPreset(unsigned int index, bool hardCut)
779783
populatePresetMenu();
780784

781785
*m_presetPos = m_presetChooser->begin(index);
782-
switchPreset(hardCut);
786+
if(!startPresetTransition(hardCut)) {
787+
selectRandom(hardCut);
788+
}
783789
}
784790

785791
// populatePresetMenu is called when a preset is loaded.
@@ -809,44 +815,48 @@ void projectM::populatePresetMenu()
809815
}
810816
}
811817
}
812-
void projectM::switchPreset(const bool hardCut) {
813-
std::string result;
814818

815-
if (!hardCut) {
816-
result = switchPreset(m_activePreset2);
817-
} else {
818-
result = switchPreset(m_activePreset);
819-
if (result.empty())
820-
timeKeeper->StartPreset();
821-
}
819+
bool projectM::startPresetTransition(bool hard_cut) {
820+
std::unique_ptr<Preset> new_preset = switchToCurrentPreset();
821+
if (new_preset == nullptr) {
822+
presetSwitchFailedEvent(hard_cut, **m_presetPos, "fake error");
823+
errorLoadingCurrentPreset = true;
824+
populatePresetMenu();
825+
return false;
826+
}
822827

823-
if (result.empty() && !hardCut) {
824-
timeKeeper->StartSmoothing();
825-
}
828+
if (hard_cut) {
829+
m_activePreset = std::move(new_preset);
830+
timeKeeper->StartPreset();
831+
} else {
832+
m_activePreset2 = std::move(new_preset);
833+
timeKeeper->StartPreset();
834+
timeKeeper->StartSmoothing();
835+
}
826836

827-
if (result.empty()) {
828-
presetSwitchedEvent(hardCut, **m_presetPos);
829-
errorLoadingCurrentPreset = false;
830-
} else {
831-
presetSwitchFailedEvent(hardCut, **m_presetPos, result);
832-
errorLoadingCurrentPreset = true;
833-
}
837+
presetSwitchedEvent(hard_cut, **m_presetPos);
838+
errorLoadingCurrentPreset = false;
834839

835-
populatePresetMenu();
836-
}
840+
populatePresetMenu();
837841

842+
return true;
843+
}
838844

839845
void projectM::selectRandom(const bool hardCut) {
840846
if (m_presetChooser->empty())
841847
return;
842848
presetHistory.push_back(m_presetPos->lastIndex());
849+
850+
for(int i = 0; i < kMaxSwitchRetries; ++i) {
851+
*m_presetPos = m_presetChooser->weightedRandom(hardCut);
852+
if(startPresetTransition(hardCut)) {
853+
break;
854+
}
855+
}
843856
// If presetHistory is tracking more than 10, then delete the oldest entry so we cap to a history of 10.
844857
if (presetHistory.size() >= 10)
845858
presetHistory.erase(presetHistory.begin());
846859
presetFuture.clear();
847-
*m_presetPos = m_presetChooser->weightedRandom(hardCut);
848-
849-
switchPreset(hardCut);
850860

851861
}
852862

@@ -860,11 +870,13 @@ void projectM::selectPrevious(const bool hardCut) {
860870
presetHistory.pop_back();
861871
}
862872
else {
863-
// if we are not shuffling or there is no random future history, then let's not track a random vector and move fowards in the preset index.
873+
// if we are not shuffling or there is no random future history, then let's not track a random vector and move backwards in the preset index.
864874
presetHistory.clear();
865875
presetFuture.clear();
866876
m_presetChooser->previousPreset(*m_presetPos);
867-
switchPreset(hardCut);
877+
if(!startPresetTransition(hardCut)) {
878+
selectRandom(hardCut);
879+
}
868880
}
869881
}
870882

@@ -877,45 +889,52 @@ void projectM::selectNext(const bool hardCut) {
877889
presetFuture.pop_back();
878890
}
879891
else {
880-
// if we are not shuffling or there is no random history, then let's not track a random vector and move backwards in the preset index.
892+
// if we are not shuffling or there is no random history, then let's not track a random vector and move forwards in the preset index.
881893
presetFuture.clear();
882894
presetHistory.clear();
883895
m_presetChooser->nextPreset(*m_presetPos);
884-
switchPreset(hardCut);
896+
if(!startPresetTransition(hardCut)) {
897+
selectRandom(hardCut);
898+
}
885899
}
886900
}
887901

888902
/**
889-
* Switches to the target preset.
890-
* @param targetPreset
891-
* @return a message indicating an error, empty otherwise.
892-
*/
893-
std::string projectM::switchPreset(std::unique_ptr<Preset> & targetPreset) {
894-
895-
std::string result;
896-
903+
* Switches the pipeline and renderer to the current preset.
904+
* @return the resulting Preset object, or nullptr on failure.
905+
*/
906+
std::unique_ptr<Preset> projectM::switchToCurrentPreset() {
907+
std::unique_ptr<Preset> new_preset;
897908
#ifdef SYNC_PRESET_SWITCHES
898-
pthread_mutex_lock(&preset_mutex);
909+
pthread_mutex_lock(&preset_mutex);
899910
#endif
900-
try {
901-
targetPreset = m_presetPos->allocate();
902-
} catch (const PresetFactoryException & e) {
911+
try {
912+
new_preset = m_presetPos->allocate();
913+
} catch (const PresetFactoryException &e) {
914+
std::cerr << "problem allocating target preset: " << e.message()
915+
<< std::endl;
916+
}
917+
918+
if (new_preset == nullptr) {
903919
#ifdef SYNC_PRESET_SWITCHES
904-
pthread_mutex_unlock(&preset_mutex);
920+
pthread_mutex_unlock(&preset_mutex);
905921
#endif
906-
std::cerr << "problem allocating target preset: " << e.message() << std::endl;
907-
return e.message();
908-
}
909-
910-
// Set preset name here- event is not done because at the moment this function is oblivious to smooth/hard switches
911-
renderer->setPresetName(targetPreset->name());
912-
result = renderer->SetPipeline(targetPreset->pipeline());
922+
std::cerr << "Could not switch to current preset" << std::endl;
923+
return nullptr;
924+
}
925+
926+
// Set preset name here- event is not done because at the moment this function
927+
// is oblivious to smooth/hard switches
928+
renderer->setPresetName(new_preset->name());
929+
std::string result = renderer->SetPipeline(new_preset->pipeline());
930+
if (!result.empty()) {
931+
std::cerr << "problem setting pipeline: " << result << std::endl;
932+
}
913933

914934
#ifdef SYNC_PRESET_SWITCHES
915-
pthread_mutex_unlock(&preset_mutex);
935+
pthread_mutex_unlock(&preset_mutex);
916936
#endif
917-
918-
return result;
937+
return new_preset;
919938
}
920939

921940
void projectM::setPresetLock ( bool isLocked )

src/libprojectM/projectM.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,8 @@ class DLLEXPORT projectM
373373

374374
Pipeline* currentPipe;
375375

376-
std::string switchPreset(std::unique_ptr<Preset> & targetPreset);
377-
void switchPreset(const bool hardCut);
376+
std::unique_ptr<Preset> switchToCurrentPreset();
377+
bool startPresetTransition(bool hard_cut);
378378

379379

380380

0 commit comments

Comments
 (0)