]> git.cworth.org Git - apitrace/blobdiff - glstate.cpp
Avoid pointless data structure copying.
[apitrace] / glstate.cpp
index 1050f98868ecb4452a16510b4bd10824f957f555..b07550966b8c403b9dd1618731773e427a09a852 100644 (file)
@@ -29,6 +29,7 @@
 #include <algorithm>
 #include <iostream>
 #include <map>
+#include <sstream>
 
 #include "image.hpp"
 #include "json.hpp"
@@ -186,7 +187,7 @@ dumpCurrentProgramObj(JSONWriter &json)
     }
 
     GLint attached_shaders = 0;
-    glGetProgramivARB(programObj, GL_OBJECT_ATTACHED_OBJECTS_ARB, &attached_shaders);
+    glGetObjectParameterivARB(programObj, GL_OBJECT_ATTACHED_OBJECTS_ARB, &attached_shaders);
     if (!attached_shaders) {
         return;
     }
@@ -209,42 +210,157 @@ dumpCurrentProgramObj(JSONWriter &json)
     }
 }
 
+
 static void
-dumpUniform(JSONWriter &json, GLint program, GLenum type, const GLchar *name) {
+dumpUniform(JSONWriter &json, GLint program, GLint size, GLenum type, const GLchar *name) {
     
-    GLenum basicType;
-    GLint length;
-
-    switch (type) {
-    case GL_FLOAT_VEC4:
-        basicType = GL_FLOAT;
-        length = 4;
-        break;
-    case GL_FLOAT_MAT4:
-        basicType = GL_FLOAT;
-        length = 4*4;
-        break;
-    default:
-        json.writeNull();
+    GLenum elemType;
+    GLint numElems;
+    __gl_uniform_size(type, elemType, numElems);
+    if (elemType == GL_NONE) {
         return;
     }
-    
-    GLint location = glGetUniformLocation(program, name);
 
     GLfloat fvalues[4*4];
+    GLdouble dvalues[4*4];
+    GLint ivalues[4*4];
+    GLuint uivalues[4*4];
+
+    GLint i, j;
+
+    for (i = 0; i < size; ++i) {
+        std::stringstream ss;
+        ss << name;
+
+        if (size > 1) {
+            ss << '[' << i << ']';
+        }
+
+        std::string elemName = ss.str();
+
+        json.beginMember(elemName);
+
+        GLint location = glGetUniformLocation(program, elemName.c_str());
+
+        if (numElems > 1) {
+            json.beginArray();
+        }
+
+        switch (elemType) {
+        case GL_FLOAT:
+            glGetUniformfv(program, location, fvalues);
+            for (j = 0; j < numElems; ++j) {
+                json.writeNumber(fvalues[j]);
+            }
+            break;
+        case GL_DOUBLE:
+            glGetUniformdv(program, location, dvalues);
+            for (j = 0; j < numElems; ++j) {
+                json.writeNumber(dvalues[j]);
+            }
+            break;
+        case GL_INT:
+            glGetUniformiv(program, location, ivalues);
+            for (j = 0; j < numElems; ++j) {
+                json.writeNumber(ivalues[j]);
+            }
+            break;
+        case GL_UNSIGNED_INT:
+            glGetUniformuiv(program, location, uivalues);
+            for (j = 0; j < numElems; ++j) {
+                json.writeNumber(uivalues[j]);
+            }
+            break;
+        case GL_BOOL:
+            glGetUniformiv(program, location, ivalues);
+            for (j = 0; j < numElems; ++j) {
+                json.writeBool(ivalues[j]);
+            }
+            break;
+        default:
+            assert(0);
+            break;
+        }
 
-    json.beginArray();
-    switch (basicType) {
-    case GL_FLOAT:
-        glGetUniformfv(program, location, fvalues);
-        for (GLint index = 0; index < length; ++index) {
-            json.writeNumber(fvalues[index]);
+        if (numElems > 1) {
+            json.endArray();
         }
-        break;
+
+        json.endMember();
     }
-    json.endArray();
 }
 
+
+static void
+dumpUniformARB(JSONWriter &json, GLhandleARB programObj, GLint size, GLenum type, const GLchar *name) {
+
+    GLenum elemType;
+    GLint numElems;
+    __gl_uniform_size(type, elemType, numElems);
+    if (elemType == GL_NONE) {
+        return;
+    }
+
+    GLfloat fvalues[4*4];
+    GLint ivalues[4*4];
+
+    GLint i, j;
+
+    for (i = 0; i < size; ++i) {
+        std::stringstream ss;
+        ss << name;
+
+        if (size > 1) {
+            ss << '[' << i << ']';
+        }
+
+        std::string elemName = ss.str();
+
+        json.beginMember(elemName);
+
+        GLint location = glGetUniformLocationARB(programObj, elemName.c_str());
+
+        if (numElems > 1) {
+            json.beginArray();
+        }
+
+        switch (elemType) {
+        case GL_DOUBLE:
+            // glGetUniformdvARB does not exists
+        case GL_FLOAT:
+            glGetUniformfvARB(programObj, location, fvalues);
+            for (j = 0; j < numElems; ++j) {
+                json.writeNumber(fvalues[j]);
+            }
+            break;
+        case GL_UNSIGNED_INT:
+            // glGetUniformuivARB does not exists
+        case GL_INT:
+            glGetUniformivARB(programObj, location, ivalues);
+            for (j = 0; j < numElems; ++j) {
+                json.writeNumber(ivalues[j]);
+            }
+            break;
+        case GL_BOOL:
+            glGetUniformivARB(programObj, location, ivalues);
+            for (j = 0; j < numElems; ++j) {
+                json.writeBool(ivalues[j]);
+            }
+            break;
+        default:
+            assert(0);
+            break;
+        }
+
+        if (numElems > 1) {
+            json.endArray();
+        }
+
+        json.endMember();
+    }
+}
+
+
 static inline void
 dumpCurrentProgramUniforms(JSONWriter &json)
 {
@@ -273,18 +389,41 @@ dumpCurrentProgramUniforms(JSONWriter &json)
         GLenum type = GL_NONE;
         glGetActiveUniform(program, index, active_uniform_max_length, &length, &size, &type, name);
 
+        dumpUniform(json, program, size, type, name);
+    }
 
-        json.beginMember(name);
-        json.beginObject();
-        json.writeNumberMember("size", size);
-        json.writeStringMember("type", enumToString(type));
-        
-        json.beginMember("value");
-        dumpUniform(json, program, type, name);
-        json.endMember();
+    delete [] name;
+}
 
-        json.endObject();
-        json.endMember();
+
+static inline void
+dumpCurrentProgramUniformsARB(JSONWriter &json)
+{
+    GLhandleARB programObj = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
+    if (!programObj) {
+        return;
+    }
+
+    GLint active_uniforms = 0;
+    glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &active_uniforms);
+    if (!active_uniforms) {
+        return;
+    }
+
+    GLint active_uniform_max_length = 0;
+    glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB, &active_uniform_max_length);
+    GLchar *name = new GLchar[active_uniform_max_length];
+    if (!name) {
+        return;
+    }
+
+    for (GLint index = 0; index < active_uniforms; ++index) {
+        GLsizei length = 0;
+        GLint size = 0;
+        GLenum type = GL_NONE;
+        glGetActiveUniformARB(programObj, index, active_uniform_max_length, &length, &size, &type, name);
+
+        dumpUniformARB(json, programObj, size, type, name);
     }
 
     delete [] name;
@@ -317,6 +456,67 @@ dumpArbProgram(JSONWriter &json, GLenum target)
 }
 
 
+static inline void
+dumpProgramUniformsARB(JSONWriter &json, GLenum target, const char *prefix)
+{
+    if (!glIsEnabled(target)) {
+        return;
+    }
+
+    GLint program_parameters = 0;
+    glGetProgramivARB(target, GL_PROGRAM_PARAMETERS_ARB, &program_parameters);
+    if (!program_parameters) {
+        return;
+    }
+
+    GLint max_program_local_parameters = 0;
+    glGetProgramivARB(target, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &max_program_local_parameters);
+    for (GLuint index = 0; index < max_program_local_parameters; ++index) {
+        GLdouble params[4] = {0, 0, 0, 0};
+        glGetProgramLocalParameterdvARB(target, index, params);
+
+        if (!params[0] && !params[1] && !params[2] && !params[3]) {
+            continue;
+        }
+
+        char name[256];
+        snprintf(name, sizeof name, "%sprogram.local[%u]", prefix, index);
+
+        json.beginMember(name);
+        json.beginArray();
+        json.writeNumber(params[0]);
+        json.writeNumber(params[1]);
+        json.writeNumber(params[2]);
+        json.writeNumber(params[3]);
+        json.endArray();
+        json.endMember();
+    }
+
+    GLint max_program_env_parameters = 0;
+    glGetProgramivARB(target, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &max_program_env_parameters);
+    for (GLuint index = 0; index < max_program_env_parameters; ++index) {
+        GLdouble params[4] = {0, 0, 0, 0};
+        glGetProgramEnvParameterdvARB(target, index, params);
+
+        if (!params[0] && !params[1] && !params[2] && !params[3]) {
+            continue;
+        }
+
+        char name[256];
+        snprintf(name, sizeof name, "%sprogram.env[%u]", prefix, index);
+
+        json.beginMember(name);
+        json.beginArray();
+        json.writeNumber(params[0]);
+        json.writeNumber(params[1]);
+        json.writeNumber(params[2]);
+        json.writeNumber(params[3]);
+        json.endArray();
+        json.endMember();
+    }
+}
+
+
 static inline void
 dumpShaders(JSONWriter &json)
 {
@@ -337,6 +537,9 @@ dumpUniforms(JSONWriter &json)
     json.beginMember("uniforms");
     json.beginObject();
     dumpCurrentProgramUniforms(json);
+    dumpCurrentProgramUniformsARB(json);
+    dumpProgramUniformsARB(json, GL_FRAGMENT_PROGRAM_ARB, "fp.");
+    dumpProgramUniformsARB(json, GL_VERTEX_PROGRAM_ARB, "vp.");
     json.endObject();
     json.endMember(); // uniforms
 }