]> git.tdb.fi Git - libs/gl.git/blobdiff - source/programbuilder.cpp
Inline variables which are simple aliases, even if not optimizing
[libs/gl.git] / source / programbuilder.cpp
index 0f29675f19dd3e45e4a63633747c6d31093f5680..bf89e7db8270ddb552ab8d3eebe49bbd687047aa 100644 (file)
@@ -292,11 +292,8 @@ void ProgramBuilder::add_shaders(Program &prog) const
                }
        }
 
-       if(optimize)
-       {
-               for(list<ShaderVariable *>::const_iterator i=resolved_vars.begin(); i!=resolved_vars.end(); ++i)
-                       (*i)->check_inline(features.legacy);
-       }
+       for(list<ShaderVariable *>::const_iterator i=resolved_vars.begin(); i!=resolved_vars.end(); ++i)
+               (*i)->check_inline(features.legacy, !optimize);
 
        prog.attach_shader_owned(new VertexShader(create_source(resolved_vars, VERTEX)));
        prog.attach_shader_owned(new FragmentShader(create_source(resolved_vars, FRAGMENT)));
@@ -624,19 +621,39 @@ void ProgramBuilder::ShaderVariable::update_reference(ShaderVariable &from, Shad
                resolve_space(to.resolved_space);
 }
 
-void ProgramBuilder::ShaderVariable::check_inline(bool allow_legacy)
+void ProgramBuilder::ShaderVariable::check_inline(bool allow_legacy, bool trivial_only)
 {
        if(variable->expression)
        {
                if(!allow_legacy && !strncmp(variable->expression, "gl_", 3))
                        return;
 
+               // Never inline goal variables
                unsigned total_refs = referenced_by.size();
+               if(!total_refs)
+                       return;
+
+               // Inline an expression consisting of a single identifier
+               unsigned start, length;
+               if(parse_identifier(variable->expression, start, length))
+                       if(start==0 && variable->expression[length]==0)
+                       {
+                               inlined = true;
+                               return;
+                       }
+
+               if(trivial_only)
+                       return;
+
                unsigned in_scope_refs = 0;
                for(list<ShaderVariable *>::const_iterator i=referenced_by.begin(); i!=referenced_by.end(); ++i)
                        if((*i)->variable->scope==variable->scope)
                                ++in_scope_refs;
-               if(total_refs==1 || (total_refs>0 && in_scope_refs==0))
+
+               /* Inline if there's only one ref, or if all refs are in other scopes.
+               In the latter case, the actual inlining will happen in the interface
+               variable assignment. */
+               if(total_refs==1 || in_scope_refs==0)
                {
                        inlined = true;
                        unsigned level = 0;