]> git.tdb.fi Git - libs/gl.git/commitdiff
Redesign loading of GLSL sources
authorMikko Rasa <tdb@tdb.fi>
Fri, 23 Apr 2021 21:43:56 +0000 (00:43 +0300)
committerMikko Rasa <tdb@tdb.fi>
Fri, 23 Apr 2021 21:43:56 +0000 (00:43 +0300)
There's now a new class which holds parsed modules.  Parser no longer
creates modules and the parse functions take the target module as a
parameter.

source/glsl/builtin.cpp
source/glsl/compiler.cpp
source/glsl/compiler.h
source/glsl/modulecache.cpp [new file with mode: 0644]
source/glsl/modulecache.h [new file with mode: 0644]
source/glsl/parser.cpp
source/glsl/parser.h

index 12602707db80ca5043b6582f5b6917422cb2f477..b9fe487c7bb2f810360918167df628d05a5acbfb 100644 (file)
@@ -28,8 +28,9 @@ Module *get_builtins_module()
                if(!io)
                        return 0;
 
-               Parser parser;
-               Module *module = new Module(parser.parse(*io, "<builtin>", BUILTIN_SOURCE));
+               RefPtr<Module> module = new Module;
+               Parser parser(0);
+               parser.parse(*module, *io, "<builtin>", BUILTIN_SOURCE);
 
                NodeList<Statement> &shared_body = module->shared.content.body;
                NodeList<Statement>::iterator insert_point = shared_body.begin();
@@ -73,7 +74,7 @@ Module *get_builtins_module()
                for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
                        populate_types(*i);
 
-               builtins_module = module;
+               builtins_module = module.release();
        }
        return builtins_module.get();
 }
index 74eec856d86a154561669ab9a1745793236e945e..5b488f4d4a8f74ac1216e1f6be193b9510d95f63 100644 (file)
@@ -8,10 +8,10 @@
 #include "finalize.h"
 #include "generate.h"
 #include "glsl_error.h"
+#include "modulecache.h"
 #include "optimize.h"
 #include "output.h"
 #include "resolve.h"
-#include "resources.h"
 #include "spirv.h"
 #include "validate.h"
 
@@ -53,17 +53,17 @@ void Compiler::clear()
 void Compiler::set_source(const string &source, const string &src_name)
 {
        clear();
-       Parser parser;
        imported_names.push_back(src_name);
-       append_module(parser.parse(source, src_name, 1), 0);
+       ModuleCache mod_cache(0);
+       append_module(mod_cache.add_module(source, src_name), mod_cache);
 }
 
 void Compiler::load_source(IO::Base &io, DataFile::Collection *res, const string &src_name)
 {
        clear();
-       Parser parser;
        imported_names.push_back(src_name);
-       append_module(parser.parse(io, src_name, 1), res);
+       ModuleCache mod_cache(res);
+       append_module(mod_cache.add_module(io, src_name), mod_cache);
 }
 
 void Compiler::load_source(IO::Base &io, const string &src_name)
@@ -223,7 +223,7 @@ string Compiler::get_diagnostics() const
        return combined;
 }
 
-void Compiler::append_module(Module &mod, DataFile::Collection *res)
+void Compiler::append_module(const Module &mod, ModuleCache &mod_cache)
 {
        module->source_map.merge_from(mod.source_map);
 
@@ -232,15 +232,14 @@ void Compiler::append_module(Module &mod, DataFile::Collection *res)
                if(Import *imp = dynamic_cast<Import *>(i->get()))
                        imports.push_back(imp);
        for(vector<Import *>::iterator i=imports.begin(); i!=imports.end(); ++i)
-               import(res, (*i)->module);
-       NodeRemover().apply(mod.shared, set<Node *>(imports.begin(), imports.end()));
+               import(mod_cache, (*i)->module);
 
        append_stage(mod.shared);
-       for(list<Stage>::iterator i=mod.stages.begin(); i!=mod.stages.end(); ++i)
+       for(list<Stage>::const_iterator i=mod.stages.begin(); i!=mod.stages.end(); ++i)
                append_stage(*i);
 }
 
-void Compiler::append_stage(Stage &stage)
+void Compiler::append_stage(const Stage &stage)
 {
        Stage *target = 0;
        if(stage.type==Stage::SHARED)
@@ -264,22 +263,18 @@ void Compiler::append_stage(Stage &stage)
 
        if(stage.required_features.glsl_version>target->required_features.glsl_version)
                target->required_features.glsl_version = stage.required_features.glsl_version;
-       for(NodeList<Statement>::iterator i=stage.content.body.begin(); i!=stage.content.body.end(); ++i)
-               target->content.body.push_back(*i);
+       for(NodeList<Statement>::const_iterator i=stage.content.body.begin(); i!=stage.content.body.end(); ++i)
+               if(!dynamic_cast<Import *>(i->get()))
+                       target->content.body.push_back(*i);
 }
 
-void Compiler::import(DataFile::Collection *resources, const string &name)
+void Compiler::import(ModuleCache &mod_cache, const string &name)
 {
-       string fn = name+".glsl";
-       if(find(imported_names, fn)!=imported_names.end())
+       if(find(imported_names, name)!=imported_names.end())
                return;
-       imported_names.push_back(fn);
+       imported_names.push_back(name);
 
-       RefPtr<IO::Seekable> io = (resources ? resources->open_raw(fn) : Resources::get_builtins().open(fn));
-       if(!io)
-               throw runtime_error(format("module %s not found", name));
-       Parser import_parser;
-       append_module(import_parser.parse(*io, fn, module->source_map.get_count()), resources);
+       append_module(mod_cache.get_module(name), mod_cache);
 }
 
 void Compiler::generate(Stage &stage)
index 51b4f00a683059579157297c1ca9803e7aff9994..3b540a8c9d20b8828b9aaa25c033a0b3bf97b043 100644 (file)
@@ -126,13 +126,13 @@ public:
 
 private:
        /** Appends a module to the target, processing any imports found in it. */
-       void append_module(Module &, DataFile::Collection *);
+       void append_module(const Module &, ModuleCache &);
 
        /** Appends a single stage to the matching stage of the target. */
-       void append_stage(Stage &);
+       void append_stage(const Stage &);
 
        /// Imports a module by name and appends it to the target. */
-       void import(DataFile::Collection *, const std::string &);
+       void import(ModuleCache &, const std::string &);
 
        /** Generates any implicitly defines syntactic structures and resolves
        variables. */
diff --git a/source/glsl/modulecache.cpp b/source/glsl/modulecache.cpp
new file mode 100644 (file)
index 0000000..116eb20
--- /dev/null
@@ -0,0 +1,73 @@
+#include <msp/io/seekable.h>
+#include "modulecache.h"
+#include "parser.h"
+#include "resources.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+namespace SL {
+
+ModuleCache::ModuleCache(DataFile::Collection *r):
+       resources(r),
+       next_source(1)
+{ }
+
+ModuleCache::ModuleCache(const ModuleCache &other)
+{
+       for(map<string, Module *>::const_iterator i=other.modules.begin(); i!=other.modules.end(); ++i)
+               modules[i->first] = new Module(*i->second);
+}
+
+ModuleCache &ModuleCache::operator=(const ModuleCache &other)
+{
+       for(map<string, Module *>::iterator i=modules.begin(); i!=modules.end(); ++i)
+               delete i->second;
+       modules.clear();
+       for(map<string, Module *>::const_iterator i=other.modules.begin(); i!=other.modules.end(); ++i)
+               modules[i->first] = new Module(*i->second);
+       return *this;
+}
+
+ModuleCache::~ModuleCache()
+{
+       for(map<string, Module *>::iterator i=modules.begin(); i!=modules.end(); ++i)
+               delete i->second;
+}
+
+const Module &ModuleCache::add_module(const string &source, const string &src_name)
+{
+       RefPtr<Module> module = new Module;
+       Parser parser(this);
+       unsigned src_index = next_source++;
+       parser.parse(*module, source, src_name, src_index);
+       return *(modules[src_name] = module.release());
+}
+
+const Module &ModuleCache::add_module(IO::Base &io, const string &src_name)
+{
+       RefPtr<Module> module = new Module;
+       Parser parser(this);
+       unsigned src_index = next_source++;
+       parser.parse(*module, io, src_name, src_index);
+       return *(modules[src_name] = module.release());
+}
+
+const Module &ModuleCache::get_module(const string &name)
+{
+       string fn = name+".glsl";
+       map<string, Module *>::const_iterator i = modules.find(fn);
+       if(i!=modules.end())
+               return *i->second;
+
+       RefPtr<IO::Seekable> io = (resources ? resources->open_raw(fn) : Resources::get_builtins().open(fn));
+       if(!io)
+               throw runtime_error(format("module %s not found", name));
+
+       return add_module(*io, fn);
+}
+
+} // namespace SL
+} // namespace GL
+} // namespace Msp
diff --git a/source/glsl/modulecache.h b/source/glsl/modulecache.h
new file mode 100644 (file)
index 0000000..ba892f9
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef MSP_GL_SL_MODULECACHE_H_
+#define MSP_GL_SL_MODULECACHE_H_
+
+#include <msp/datafile/collection.h>
+#include "syntax.h"
+
+namespace Msp {
+namespace GL {
+namespace SL {
+
+class ModuleCache
+{
+private:
+       DataFile::Collection *resources;
+       std::map<std::string, Module *> modules;
+       unsigned next_source;
+
+public:
+       ModuleCache(DataFile::Collection *);
+       ModuleCache(const ModuleCache &);
+       ModuleCache &operator=(const ModuleCache &);
+       ~ModuleCache();
+
+       const Module &add_module(const std::string &, const std::string &);
+       const Module &add_module(IO::Base &, const std::string &);
+       const Module &get_module(const std::string &);
+};
+
+} // namespace SL
+} // namespace GL
+} // namespace Msp
+
+#endif
index 0512c10b235ea6d384d17e319d9a4a5ce3e5c7b2..cbfa593ac590671b04f077f4bd2e44136f1312c7 100644 (file)
@@ -4,6 +4,7 @@
 #include <msp/strings/utils.h>
 #include "builtin.h"
 #include "glsl_error.h"
+#include "modulecache.h"
 #include "parser.h"
 
 #undef interface
@@ -14,7 +15,8 @@ namespace Msp {
 namespace GL {
 namespace SL {
 
-Parser::Parser():
+Parser::Parser(ModuleCache *s):
+       mod_cache(s),
        preprocessor(tokenizer),
        module(0)
 {
@@ -25,20 +27,16 @@ Parser::Parser():
        preprocessor.signal_line.connect(sigc::mem_fun(this, &Parser::line_change));
 }
 
-Parser::~Parser()
-{
-       delete module;
-}
-
-Module &Parser::parse(const string &s, const string &n, int i)
+void Parser::parse(Module &m, const string &s, const string &n, int i)
 {
+       SetForScope<Module *> set_module(module, &m);
        source = s;
        parse_source(n, i);
-       return *module;
 }
 
-Module &Parser::parse(IO::Base &io, const string &n, int i)
+void Parser::parse(Module &m, IO::Base &io, const string &n, int i)
 {
+       SetForScope<Module *> set_module(module, &m);
        source = string();
        while(!io.eof())
        {
@@ -47,14 +45,10 @@ Module &Parser::parse(IO::Base &io, const string &n, int i)
                source.append(buffer, len);
        }
        parse_source(n, i);
-       return *module;
 }
 
 void Parser::parse_source(const string &name, int index)
 {
-       delete module;
-       module = new Module;
-
        cur_stage = &module->shared;
        base_index = index;
        source_index = index;
index c98867a3791e866ecd31a9c7cc5076e7443482cf..e087f27f9d0578bd6e23be8fee0c44e841cd3cb3 100644 (file)
@@ -12,9 +12,12 @@ namespace Msp {
 namespace GL {
 namespace SL {
 
+class ModuleCache;
+
 class Parser
 {
 private:
+       ModuleCache *mod_cache;
        std::string source;
        int base_index;
        int source_index;
@@ -27,11 +30,10 @@ private:
        std::vector<std::string> errors;
 
 public:
-       Parser();
-       ~Parser();
+       Parser(ModuleCache *);
 
-       Module &parse(const std::string &, const std::string &, int);
-       Module &parse(IO::Base &, const std::string &, int);
+       void parse(Module &, const std::string &, const std::string &, int);
+       void parse(Module &, IO::Base &, const std::string &, int);
 
 private:
        void parse_source(const std::string &, int);