Cleanup program binding at link time.
authorRyan C. Gordon <icculus@icculus.org>
Thu, 06 Aug 2009 14:46:32 -0400
changeset 761 3ccbd05350d6
parent 760 6dc8d2cafc58
child 762 32ab4d54e48a
Cleanup program binding at link time. Only bind program at link time if forced to, only do it once, and only reset the binding back to the original state at the end, if necessary.
mojoshader_opengl.c
--- a/mojoshader_opengl.c	Thu Aug 06 14:33:56 2009 -0400
+++ b/mojoshader_opengl.c	Thu Aug 06 14:46:32 2009 -0400
@@ -1162,7 +1162,7 @@
 
 
 static void lookup_uniforms(MOJOSHADER_glProgram *program,
-                            MOJOSHADER_glShader *shader)
+                            MOJOSHADER_glShader *shader, int *bound)
 {
     const MOJOSHADER_parseData *pd = shader->parseData;
     const MOJOSHADER_shaderType shader_type = pd->shader_type;
@@ -1183,9 +1183,12 @@
                     const int size = u->array_count;
                     GLfloat *f = (GLfloat *) alloca(sizeof (GLfloat)*(size*4));
                     fill_constant_array(f, base, size, pd);
-                    ctx->profileUseProgramObject(program);
+                    if (!(*bound))
+                    {
+                        ctx->profileUseProgramObject(program);
+                        *bound = 1;
+                    } // if
                     ctx->profileUniform4fv(pd, loc, size, f);
-                    ctx->profileUseProgramObject(ctx->bound_program);
                 } // if
             } // if
 
@@ -1203,7 +1206,7 @@
 
 
 static void lookup_samplers(MOJOSHADER_glProgram *program,
-                            MOJOSHADER_glShader *shader)
+                            MOJOSHADER_glShader *shader, int *bound)
 {
     const MOJOSHADER_parseData *pd = shader->parseData;
     const MOJOSHADER_sampler *s = pd->samplers;
@@ -1215,7 +1218,11 @@
     // Link up the Samplers. These never change after link time, since they
     //  are meant to be constant texture unit ids and not textures.
 
-    ctx->profileUseProgramObject(program);
+    if (!(*bound))
+    {
+        ctx->profileUseProgramObject(program);
+        *bound = 1;
+    } // if
 
     for (i = 0; i < pd->sampler_count; i++)
     {
@@ -1223,8 +1230,6 @@
         if (loc != -1)  // maybe the Sampler was optimized out?
             ctx->profileSetSampler(loc, s[i].index);
     } // for
-
-    ctx->profileUseProgramObject(ctx->bound_program);
 } // lookup_samplers
 
 
@@ -1284,6 +1289,8 @@
 MOJOSHADER_glProgram *MOJOSHADER_glLinkProgram(MOJOSHADER_glShader *vshader,
                                                MOJOSHADER_glShader *pshader)
 {
+    int bound = 0;
+
     if ((vshader == NULL) && (pshader == NULL))
         return NULL;
 
@@ -1329,21 +1336,24 @@
             lookup_attributes(retval);
         } // if
 
-        lookup_uniforms(retval, vshader);
-        lookup_samplers(retval, vshader);
+        lookup_uniforms(retval, vshader, &bound);
+        lookup_samplers(retval, vshader, &bound);
         vshader->refcount++;
     } // if
 
     if (pshader != NULL)
     {
-        lookup_uniforms(retval, pshader);
-        lookup_samplers(retval, pshader);
+        lookup_uniforms(retval, pshader, &bound);
+        lookup_samplers(retval, pshader, &bound);
         pshader->refcount++;
     } // if
 
     if (!build_constants_lists(retval))
         goto link_program_fail;
 
+    if (bound)  // reset the old binding.
+        ctx->profileUseProgramObject(ctx->bound_program);
+
     return retval;
 
 link_program_fail:
@@ -1360,6 +1370,9 @@
     if (program != 0)
         ctx->profileDeleteProgram(program);
 
+    if (bound)
+        ctx->profileUseProgramObject(ctx->bound_program);
+
     return NULL;
 } // MOJOSHADER_glLinkProgram