From 7bff63c0377e1a92aca27cb2f22676a0924c587d Mon Sep 17 00:00:00 2001 From: Almamu Date: Sun, 6 Apr 2025 20:13:45 +0200 Subject: [PATCH] chore: changed shader compilation slightly so they're passed onto glsl just once --- src/WallpaperEngine/Logging/CLog.h | 54 ++++++++----------- .../Render/Objects/Effects/CPass.cpp | 28 +++++----- .../Render/Objects/Effects/CPass.h | 2 +- .../Render/Shaders/CCompiler.cpp | 26 ++++++--- .../Render/Shaders/CCompiler.h | 16 +++--- src/main.cpp | 2 + 6 files changed, 66 insertions(+), 62 deletions(-) diff --git a/src/WallpaperEngine/Logging/CLog.h b/src/WallpaperEngine/Logging/CLog.h index cff431c..8841d71 100644 --- a/src/WallpaperEngine/Logging/CLog.h +++ b/src/WallpaperEngine/Logging/CLog.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -17,70 +18,49 @@ class CLog { void addError (std::ostream* stream); template void out (Data... data) { - // buffer the string first - std::stringbuf buffer; - std::ostream bufferStream (&buffer); - - ((bufferStream << std::forward (data)), ...); + std::string str = this->buildBuffer (data...); // then send it to all the outputs configured for (const auto cur : this->mOutputs) - *cur << buffer.str () << std::endl; + *cur << str << std::endl; } template void debug (Data... data) { #if (!NDEBUG) && (!ERRORONLY) - // buffer the string first - std::stringbuf buffer; - std::ostream bufferStream (&buffer); - - ((bufferStream << std::forward (data)), ...); + std::string str = this->buildBuffer (data...); // then send it to all the outputs configured for (const auto cur : this->mOutputs) - *cur << buffer.str () << std::endl; + *cur << str << std::endl; #endif /* DEBUG */ } template void debugerror (Data... data) { #if (!NDEBUG) && (ERRORONLY) - // buffer the string first - std::stringbuf buffer; - std::ostream bufferStream (&buffer); - - ((bufferStream << std::forward (data)), ...); + std::string str = this->buildBuffer (data...); // then send it to all the outputs configured for (const auto cur : this->mOutputs) - *cur << buffer.str () << std::endl; + *cur << str << std::endl; #endif /* DEBUG */ } template void error (Data... data) { - // buffer the string first - std::stringbuf buffer; - std::ostream bufferStream (&buffer); - - ((bufferStream << std::forward (data)), ...); + std::string str = this->buildBuffer (data...); // then send it to all the outputs configured for (const auto cur : this->mErrors) - *cur << buffer.str () << std::endl; + *cur << str << std::endl; } template [[noreturn]] void exception (Data... data) { - // buffer the string first - std::stringbuf buffer; - std::ostream bufferStream (&buffer); - - ((bufferStream << std::forward (data)), ...); - + std::string str = this->buildBuffer (data...); // then send it to all the outputs configured for (const auto cur : this->mErrors) - *cur << buffer.str () << std::endl; + *cur << str << std::endl; // now throw the exception - throw EX (buffer.str ()); + throw EX (str); } template [[noreturn]] void exception (Data... data) { @@ -90,6 +70,16 @@ class CLog { static CLog& get (); private: + template std::string buildBuffer (Data... data) { + // buffer the string first + std::stringbuf buffer; + std::ostream bufferStream (&buffer); + + ((bufferStream << std::forward (data)), ...); + + return buffer.str (); + } + std::vector mOutputs; std::vector mErrors; static std::shared_ptr sInstance; diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp index 4d6423b..20a84df 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp @@ -282,14 +282,11 @@ Core::Objects::Images::Materials::CPass* CPass::getPass () { return this->m_pass; } -GLuint CPass::compileShader (Render::Shaders::CCompiler* shader, GLuint type) { +GLuint CPass::compileShader (const char* shader, GLuint type) { // reserve shaders in OpenGL const GLuint shaderID = glCreateShader (type); - // give shader's source code to OpenGL to be compiled - const char* sourcePointer = shader->getCompiled ().c_str (); - - glShaderSource (shaderID, 1, &sourcePointer, nullptr); + glShaderSource (shaderID, 1, &shader, nullptr); glCompileShader (shaderID); GLint result = GL_FALSE; @@ -307,7 +304,7 @@ GLuint CPass::compileShader (Render::Shaders::CCompiler* shader, GLuint type) { glGetShaderInfoLog (shaderID, infoLogLength, nullptr, logBuffer); // throw an exception about the issue std::stringstream buffer; - buffer << logBuffer << std::endl << "Compiled source code:" << std::endl << shader->getCompiled (); + buffer << logBuffer << std::endl << "Compiled source code:" << std::endl << shader; // free the buffer delete [] logBuffer; // throw an exception @@ -335,19 +332,24 @@ void CPass::setupShaders () { this->m_fragShader = new Render::Shaders::CCompiler ( this->m_material->getImage ()->getContainer (), this->m_pass->getShader (), Shaders::CGLSLContext::ShaderType_Pixel, this->m_pass->getCombos (), &m_foundCombos, this->m_pass->getTextures (), this->m_pass->getConstants ()); - this->m_fragShader->compile (); this->m_vertShader = new Render::Shaders::CCompiler ( this->m_material->getImage ()->getContainer (), this->m_pass->getShader (), Shaders::CGLSLContext::ShaderType_Vertex, this->m_pass->getCombos (), &m_foundCombos, this->m_pass->getTextures (), this->m_pass->getConstants ()); - this->m_vertShader->compile (); - // they're re-compiled to ensure they are using the latest constants available - this->m_fragShader->compile (); - this->m_vertShader->compile (); + // precompile shaders once so all the data is discovered + this->m_fragShader->precompile (); + this->m_vertShader->precompile (); + + // precompile them again once all the data is available + this->m_fragShader->precompile (); + this->m_vertShader->precompile (); + + std::string fragmentCode = this->m_fragShader->compile (); + std::string vertexCode = this->m_vertShader->compile (); // compile the shaders - const GLuint vertexShaderID = compileShader (this->m_vertShader, GL_VERTEX_SHADER); - const GLuint fragmentShaderID = compileShader (this->m_fragShader, GL_FRAGMENT_SHADER); + const GLuint vertexShaderID = compileShader (vertexCode.c_str (), GL_VERTEX_SHADER); + const GLuint fragmentShaderID = compileShader (fragmentCode.c_str (), GL_FRAGMENT_SHADER); // create the final program this->m_programID = glCreateProgram (); // link the shaders together diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.h b/src/WallpaperEngine/Render/Objects/Effects/CPass.h index 7bb502e..76783fc 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.h +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.h @@ -95,7 +95,7 @@ class CPass final : public Helpers::CContextAware { const GLuint* value; }; - static GLuint compileShader (Render::Shaders::CCompiler* shader, GLuint type); + static GLuint compileShader (const char* shader, GLuint type); void setupTextures (); void setupShaders (); void setupShaderVariables (); diff --git a/src/WallpaperEngine/Render/Shaders/CCompiler.cpp b/src/WallpaperEngine/Render/Shaders/CCompiler.cpp index 8cc3142..08bc9f0 100644 --- a/src/WallpaperEngine/Render/Shaders/CCompiler.cpp +++ b/src/WallpaperEngine/Render/Shaders/CCompiler.cpp @@ -64,11 +64,7 @@ std::string CCompiler::lookupShaderFile (const std::string& filename) { } } -std::string& CCompiler::getCompiled () { - return this->m_compiledContent; -} - -void CCompiler::compile () { +void CCompiler::precompile () { // reset include contents as the compilation requires this to be re-processed this->m_includeContent = ""; std::string precompile = "#version 330\n" @@ -189,6 +185,20 @@ void CCompiler::compile () { end = start; } + // reset end so we start from the beginning + end = 0; + + // comment out requires + while((start = precompile.find("#require", end)) != std::string::npos) { + // TODO: CHECK FOR ERRORS HERE + size_t lineEnd = precompile.find_first_of('\n', start); + sLog.out("Shader has a require block ", precompile.substr (start, lineEnd - start)); + // replace the first two letters with a comment so the filelength doesn't change + precompile = precompile.replace(start, 2, "//"); + + // go to the end of the line + end = lineEnd; + } // include content might have more includes, so also handle those /*end = 0; @@ -232,8 +242,12 @@ void CCompiler::compile () { end = end + this->m_includeContent.length () + 1; }*/ + this->m_processedContent = precompile; +} + +std::string CCompiler::compile () { // content should be ready, finally ask glslang to compile the shader - this->m_compiledContent = CGLSLContext::get().toGlsl (precompile, this->m_type); + return CGLSLContext::get().toGlsl (this->m_processedContent, this->m_type); } void CCompiler::parseComboConfiguration (const std::string& content, int defaultValue) { diff --git a/src/WallpaperEngine/Render/Shaders/CCompiler.h b/src/WallpaperEngine/Render/Shaders/CCompiler.h index f77af3e..7392264 100644 --- a/src/WallpaperEngine/Render/Shaders/CCompiler.h +++ b/src/WallpaperEngine/Render/Shaders/CCompiler.h @@ -40,17 +40,14 @@ class CCompiler { std::map* foundCombos, const std::vector& textures, const std::map& constants); /** - * Performs the actual pre-compilation/pre-processing over the shader files - * This step is kinda big, replaces variables names on sVariableReplacement, - * ensures #include directives are correctly handled - * and takes care of attribute comments for the wallpaper engine specifics + * Pre-processes the shader to detect variables, process includes and other small things WallpaperEngine + * does to shaders before actually using them */ - void compile (); + void precompile (); /** - * @return The compiled shader's text (if available) + * Performs the final processing of the shader doing a few last transformations through glslang */ - std::string& getCompiled (); - + std::string compile (); /** * Searches the list of parameters available for the parameter with the given value * @@ -58,7 +55,6 @@ class CCompiler { * @return The shader information */ Variables::CShaderVariable* findParameter (const std::string& identifier); - /** * @return The list of parameters available for this shader with their default values */ @@ -108,7 +104,7 @@ class CCompiler { /** * The final, compiled content ready to be used by OpenGL */ - std::string m_compiledContent; + std::string m_processedContent; /** * The contents of all the included files */ diff --git a/src/main.cpp b/src/main.cpp index 1d6dcf8..068579f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -50,6 +50,7 @@ int main (int argc, char* argv[]) { // attach signals to gracefully stop std::signal (SIGINT, signalhandler); std::signal (SIGTERM, signalhandler); + std::signal (SIGKILL, signalhandler); // show the wallpaper application app->show (); @@ -57,6 +58,7 @@ int main (int argc, char* argv[]) { // remove signal handlers before destroying app std::signal (SIGINT, SIG_DFL); std::signal (SIGTERM, SIG_DFL); + std::signal (SIGKILL, SIG_DFL); delete app;