]> git.tdb.fi Git - libs/gl.git/commitdiff
Rearrange material-related state management in RenderPass
authorMikko Rasa <tdb@tdb.fi>
Mon, 19 Apr 2021 08:14:51 +0000 (11:14 +0300)
committerMikko Rasa <tdb@tdb.fi>
Mon, 19 Apr 2021 15:02:20 +0000 (18:02 +0300)
The change in texture handling allows some simplifications here since
material textures no longer need to set any uniforms.  Creation of
material shader while loading is deferred to finish() so it isn't done
needlessly.

source/materials/renderpass.cpp
source/materials/renderpass.h

index e6a9a0a4145e87e8c2a30246f1d20f96c0228c57..951cbb5d1557e5f16aad121b8bef7d10e4a78c46 100644 (file)
@@ -25,11 +25,8 @@ RenderPass::RenderPass():
        back_faces(false)
 { }
 
-void RenderPass::finalize_material(DataFile::Collection *coll)
+void RenderPass::set_material_textures()
 {
-       maybe_create_material_shader(coll);
-       ensure_private_shader_data();
-
        const Tag *material_texture_tags = material->get_texture_tags();
        for(const Tag *tag=material_texture_tags; tag->id; ++tag)
                set_texture(*tag, material->get_texture(*tag), material->get_sampler());
@@ -46,7 +43,7 @@ void RenderPass::maybe_create_material_shader(DataFile::Collection *coll)
                shprog.keep();
        }
        else
-               throw invalid_operation("no collection");
+               throw invalid_operation("RenderPass::maybe_create_material_shader");
 
        if(shdata)
                shdata = new ProgramData(*shdata, shprog.get());
@@ -54,25 +51,12 @@ void RenderPass::maybe_create_material_shader(DataFile::Collection *coll)
        shprog_from_material = true;
 }
 
-void RenderPass::ensure_private_shader_data()
-{
-       if(!shprog)
-               throw invalid_operation("RenderPass::ensure_private_shader_data");
-
-       if(!shdata)
-               shdata = new ProgramData(shprog.get());
-       else if(shdata.refcount()>1)
-               shdata = new ProgramData(*shdata);
-}
-
 void RenderPass::set_shader_program(const Program *prog, const ProgramData *data)
 {
        shprog = prog;
        shprog.keep();
        shprog_from_material = false;
        shdata = (data ? new ProgramData(*data) : 0);
-       if(material)
-               finalize_material(0);
 }
 
 Tag RenderPass::get_slotted_uniform_tag(Tag slot) const
@@ -87,7 +71,8 @@ void RenderPass::set_material(const Material *mat, DataFile::Collection *coll)
 {
        material = mat;
        material.keep();
-       finalize_material(coll);
+       maybe_create_material_shader(coll);
+       set_material_textures();
 }
 
 void RenderPass::set_texture(Tag tag, const Texture *tex, const Sampler *samp)
@@ -182,6 +167,12 @@ void RenderPass::Loader::init_actions()
        add("texunit",  &Loader::texunit_named);
 }
 
+void RenderPass::Loader::finish()
+{
+       if(obj.material)
+               obj.maybe_create_material_shader(coll);
+}
+
 // Temporary compatibility feature
 string RenderPass::Loader::get_shader_name(const string &n)
 {
@@ -198,14 +189,14 @@ void RenderPass::Loader::material_inline()
        Material::GenericLoader ldr(coll);
        load_sub_with(ldr);
        obj.material = ldr.get_material();
-       obj.finalize_material(coll);
+       obj.set_material_textures();
 }
 
 void RenderPass::Loader::material(const string &name)
 {
        obj.material = &get_collection().get<Material>(name);
        obj.material.keep();
-       obj.finalize_material(coll);
+       obj.set_material_textures();
 }
 
 void RenderPass::Loader::shader(const string &n)
@@ -215,8 +206,6 @@ void RenderPass::Loader::shader(const string &n)
        obj.shprog_from_material = false;
        if(obj.shdata)
                obj.shdata = new ProgramData(*obj.shdata, obj.shprog.get());
-       if(obj.material)
-               obj.finalize_material(coll);
 }
 
 void RenderPass::Loader::texture(const string &n)
@@ -265,7 +254,10 @@ void RenderPass::Loader::uniforms()
 {
        if(!obj.shprog || obj.shprog_from_material)
                throw runtime_error("Shader is required for uniforms");
-       obj.ensure_private_shader_data();
+       if(!obj.shdata)
+               obj.shdata = new ProgramData(obj.shprog.get());
+       else if(obj.shdata.refcount()>1)
+               obj.shdata = new ProgramData(*obj.shdata);
        load_sub(*obj.shdata);
 }
 
index cb378556f27df66f35f0d448bb67ba3de9133c5e..b5b9cfb5af107149f1b01e930193aedae33539ec 100644 (file)
@@ -33,6 +33,7 @@ public:
 
        private:
                virtual void init_actions();
+               virtual void finish();
 
                static std::string get_shader_name(const std::string &);
 
@@ -83,9 +84,8 @@ public:
        RenderPass();
 
 private:
-       void finalize_material(DataFile::Collection *);
        void maybe_create_material_shader(DataFile::Collection *);
-       void ensure_private_shader_data();
+       void set_material_textures();
 
 public:
        void set_shader_program(const Program *, const ProgramData *);