]> git.cworth.org Git - apitrace/commitdiff
Reorganize glstate code.
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Thu, 19 May 2011 09:45:04 +0000 (10:45 +0100)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Thu, 19 May 2011 09:45:04 +0000 (10:45 +0100)
.gitignore
CMakeLists.txt
glretrace_main.cpp
glstate.cpp [new file with mode: 0644]
glstate.hpp
glstate.py

index 56809775248787f381496c9dda9947e767f73c92..5b141147f430453f1ae8beb65b94d41ff04beb1b 100644 (file)
@@ -35,7 +35,7 @@ dxsdk
 glproc.hpp
 glretrace
 glretrace_gl.cpp
-glstate.cpp
+glstate_params.cpp
 glxtrace.cpp
 install_manifest.txt
 qapitrace
index 41bbd6d94c589d686c1631e55acf2ec5f1df0117..44b4c84a2bba93a97f199722ffbc9e671466cdf6 100755 (executable)
@@ -306,8 +306,8 @@ add_custom_command (
 )
 
 add_custom_command (
-    OUTPUT glstate.cpp
-    COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glstate.py > ${CMAKE_CURRENT_BINARY_DIR}/glstate.cpp
+    OUTPUT glstate_params.cpp
+    COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glstate.py > ${CMAKE_CURRENT_BINARY_DIR}/glstate_params.cpp
     DEPENDS glstate.py glparams.py gltypes.py stdapi.py
 )
 
@@ -323,6 +323,7 @@ add_executable (glretrace
     glretrace_wgl.cpp
     glretrace_main.cpp
     glstate.cpp
+    glstate_params.cpp
     retrace.cpp
     ${glws}
     image.cpp 
index bfab151fde00f9885aab88cf5ea1c03065ef07d3..56113efc60c85d54e34bf88f2eb4337a263a74ed 100644 (file)
@@ -203,7 +203,7 @@ static void display(void) {
         if (!insideGlBeginEnd &&
             drawable && context &&
             call->no >= dump_state) {
-            glstate::state_dump(std::cout);
+            glstate::dumpCurrentContext(std::cout);
             exit(0);
         }
 
diff --git a/glstate.cpp b/glstate.cpp
new file mode 100644 (file)
index 0000000..a60c687
--- /dev/null
@@ -0,0 +1,643 @@
+/**************************************************************************
+ *
+ * Copyright 2011 Jose Fonseca
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include <string.h>
+#include <iostream>
+#include <algorithm>
+
+#include "image.hpp"
+#include "json.hpp"
+#include "glproc.hpp"
+#include "glsize.hpp"
+#include "glstate.hpp"
+
+
+namespace glstate {
+
+
+static void
+dumpShader(JSONWriter &json, GLuint shader)
+{
+    if (!shader) {
+        return;
+    }
+
+    GLint shader_type = 0;
+    glGetShaderiv(shader, GL_SHADER_TYPE, &shader_type);
+    if (!shader_type) {
+        return;
+    }
+
+    GLint source_length = 0;
+    glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &source_length);
+    if (!source_length) {
+        return;
+    }
+
+    GLchar *source = new GLchar[source_length];
+    GLsizei length = 0;
+    source[0] = 0;
+    glGetShaderSource(shader, source_length, &length, source);
+
+    json.beginMember(enumToString(shader_type));
+    json.writeString(source);
+    json.endMember();
+
+    delete [] source;
+}
+
+
+static void
+dumpShaderObj(JSONWriter &json, GLhandleARB shaderObj)
+{
+    if (!shaderObj) {
+        return;
+    }
+
+    GLint shader_type = 0;
+    glGetObjectParameterivARB(shaderObj, GL_OBJECT_TYPE_ARB, &shader_type);
+    if (!shader_type) {
+        return;
+    }
+
+    GLint source_length = 0;
+    glGetObjectParameterivARB(shaderObj, GL_OBJECT_SHADER_SOURCE_LENGTH_ARB, &source_length);
+    if (!source_length) {
+        return;
+    }
+
+    GLcharARB *source = new GLcharARB[source_length];
+    GLsizei length = 0;
+    source[0] = 0;
+    glGetShaderSource(shaderObj, source_length, &length, source);
+
+    json.beginMember(enumToString(shader_type));
+    json.writeString(source);
+    json.endMember();
+
+    delete [] source;
+}
+
+
+static inline void
+dumpCurrentProgram(JSONWriter &json)
+{
+    GLint program = 0;
+    glGetIntegerv(GL_CURRENT_PROGRAM, &program);
+    if (!program) {
+        return;
+    }
+
+    GLint attached_shaders = 0;
+    glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
+    if (!attached_shaders) {
+        return;
+    }
+
+    GLuint *shaders = new GLuint[attached_shaders];
+    GLsizei count = 0;
+    glGetAttachedShaders(program, attached_shaders, &count, shaders);
+    for (GLsizei i = 0; i < count; ++ i) {
+       dumpShader(json, shaders[i]);
+    }
+    delete [] shaders;
+}
+
+
+static inline void
+dumpCurrentProgramObj(JSONWriter &json)
+{
+    GLhandleARB programObj = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
+    if (!programObj) {
+        return;
+    }
+
+    GLint attached_shaders = 0;
+    glGetProgramivARB(programObj, GL_OBJECT_ATTACHED_OBJECTS_ARB, &attached_shaders);
+    if (!attached_shaders) {
+        return;
+    }
+
+    GLhandleARB *shaderObjs = new GLhandleARB[attached_shaders];
+    GLsizei count = 0;
+    glGetAttachedObjectsARB(programObj, attached_shaders, &count, shaderObjs);
+    for (GLsizei i = 0; i < count; ++ i) {
+       dumpShaderObj(json, shaderObjs[i]);
+    }
+    delete [] shaderObjs;
+}
+
+
+static inline void
+dumpArbProgram(JSONWriter &json, GLenum target)
+{
+    if (!glIsEnabled(target)) {
+        return;
+    }
+
+    GLint program_length = 0;
+    glGetProgramivARB(target, GL_PROGRAM_LENGTH_ARB, &program_length);
+    if (!program_length) {
+        return;
+    }
+
+    GLchar *source = new GLchar[program_length + 1];
+    source[0] = 0;
+    glGetProgramStringARB(target, GL_PROGRAM_STRING_ARB, source);
+    source[program_length] = 0;
+
+    json.beginMember(enumToString(target));
+    json.writeString(source);
+    json.endMember();
+
+    delete [] source;
+}
+
+
+static inline void
+dumpShaders(JSONWriter &json)
+{
+    json.beginMember("shaders");
+    json.beginObject();
+    dumpCurrentProgram(json);
+    dumpArbProgram(json, GL_FRAGMENT_PROGRAM_ARB);
+    dumpArbProgram(json, GL_VERTEX_PROGRAM_ARB);
+    json.endObject();
+    json.endMember(); //shaders
+}
+
+
+static inline void
+dumpTextureImage(JSONWriter &json, GLenum target, GLint level)
+{
+    GLint width, height = 1, depth = 1;
+
+    width = 0;
+    glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
+
+    if (target != GL_TEXTURE_1D) {
+        height = 0;
+        glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
+        if (target == GL_TEXTURE_3D) {
+            depth = 0;
+            glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth);
+        }
+    }
+
+    if (width <= 0 || height <= 0 || depth <= 0) {
+        return;
+    } else {
+        char label[512];
+
+        GLint active_texture = GL_TEXTURE0;
+        glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
+        snprintf(label, sizeof label, "%s, %s, level = %i", enumToString(active_texture), enumToString(target), level);
+
+        json.beginMember(label);
+
+        json.beginObject();
+
+        // Tell the GUI this is no ordinary object, but an image
+        json.writeStringMember("__class__", "image");
+
+        json.writeNumberMember("__width__", width);
+        json.writeNumberMember("__height__", height);
+        json.writeNumberMember("__depth__", depth);
+
+        // Hardcoded for now, but we could chose types more adequate to the
+        // texture internal format
+        json.writeStringMember("__type__", "uint8");
+        json.writeBoolMember("__normalized__", true);
+        json.writeNumberMember("__channels__", 4);
+
+        GLubyte *pixels = new GLubyte[depth*width*height*4];
+
+        glGetTexImage(target, level, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+        json.beginMember("__data__");
+        char *pngBuffer;
+        int pngBufferSize;
+        Image::writePixelsToBuffer(pixels, width, height, 4, false, &pngBuffer, &pngBufferSize);
+        json.writeBase64(pngBuffer, pngBufferSize);
+        free(pngBuffer);
+        json.endMember(); // __data__
+
+        delete [] pixels;
+        json.endObject();
+    }
+}
+
+
+static inline void
+dumpTexture(JSONWriter &json, GLenum target, GLenum binding)
+{
+    GLint texture_binding = 0;
+    glGetIntegerv(binding, &texture_binding);
+    if (!glIsEnabled(target) && !texture_binding) {
+        return;
+    }
+
+    GLint level = 0;
+    do {
+        GLint width = 0, height = 0;
+        glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
+        glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
+        if (!width || !height) {
+            break;
+        }
+
+        if (target == GL_TEXTURE_CUBE_MAP) {
+            for (int face = 0; face < 6; ++face) {
+                dumpTextureImage(json, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level);
+            }
+        } else {
+            dumpTextureImage(json, target, level);
+        }
+
+        ++level;
+    } while(true);
+}
+
+
+static inline void
+dumpTextures(JSONWriter &json)
+{
+    json.beginMember("textures");
+    json.beginObject();
+    GLint active_texture = GL_TEXTURE0;
+    glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
+    GLint max_texture_coords = 0;
+    glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);
+    GLint max_combined_texture_image_units = 0;
+    glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_combined_texture_image_units);
+    GLint max_units = std::max(max_combined_texture_image_units, max_texture_coords);
+    for (GLint unit = 0; unit < max_units; ++unit) {
+        GLenum texture = GL_TEXTURE0 + unit;
+        glActiveTexture(texture);
+        dumpTexture(json, GL_TEXTURE_1D, GL_TEXTURE_BINDING_1D);
+        dumpTexture(json, GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D);
+        dumpTexture(json, GL_TEXTURE_3D, GL_TEXTURE_BINDING_3D);
+        dumpTexture(json, GL_TEXTURE_RECTANGLE, GL_TEXTURE_BINDING_RECTANGLE);
+        dumpTexture(json, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BINDING_CUBE_MAP);
+    }
+    glActiveTexture(active_texture);
+    json.endObject();
+    json.endMember(); // textures
+}
+
+
+static bool
+getDrawableBounds(GLint *width, GLint *height) {
+#if defined(_WIN32)
+
+    HDC hDC = wglGetCurrentDC();
+    if (!hDC) {
+        return false;
+    }
+
+    HWND hWnd = WindowFromDC(hDC);
+    RECT rect;
+
+    if (!GetClientRect(hWnd, &rect)) {
+       return false;
+    }
+
+    *width  = rect.right  - rect.left;
+    *height = rect.bottom - rect.top;
+
+#elif 0 /* __APPLE__ */
+
+    CGLError CGLGetSurface(CGLContextObj, CGSConnectionID*, CGSWindowID*, CGSSurfaceID*);
+    CGError CGSGetWindowBounds(CGSConnectionID, CGWindowID, CGRect *ret);
+
+#else
+
+    Display *display;
+    Drawable drawable;
+    Window root;
+    int x, y;
+    unsigned int w, h, bw, depth;
+
+    display = glXGetCurrentDisplay();
+    if (!display) {
+        return false;
+    }
+
+    drawable = glXGetCurrentDrawable();
+    if (drawable == None) {
+        return false;
+    }
+
+    if (!XGetGeometry(display, drawable, &root, &x, &y, &w, &h, &bw, &depth)) {
+        return false;
+    }
+
+    *width = w;
+    *height = h;
+
+#endif
+
+    return true;
+}
+
+
+static inline void
+dumpDrawBufferImage(JSONWriter &json, GLenum format)
+{
+    GLint channels = __gl_format_channels(format);
+
+    GLint width, height;
+
+    if (!getDrawableBounds(&width, &height)) {
+        json.writeNull();
+    } else {
+        json.beginObject();
+
+        // Tell the GUI this is no ordinary object, but an image
+        json.writeStringMember("__class__", "image");
+
+        json.writeNumberMember("__width__", width);
+        json.writeNumberMember("__height__", height);
+        json.writeNumberMember("__depth__", 1);
+
+        // Hardcoded for now, but we could chose types more adequate to the
+        // texture internal format
+        json.writeStringMember("__type__", "uint8");
+        json.writeBoolMember("__normalized__", true);
+        json.writeNumberMember("__channels__", channels);
+
+        GLubyte *pixels = new GLubyte[width*height*channels];
+
+        GLint drawbuffer = GL_NONE;
+        GLint readbuffer = GL_NONE;
+        glGetIntegerv(GL_DRAW_BUFFER, &drawbuffer);
+        glGetIntegerv(GL_READ_BUFFER, &readbuffer);
+        glReadBuffer(drawbuffer);
+
+        glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
+        glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+        glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, pixels);
+
+        glPopClientAttrib();
+        glReadBuffer(readbuffer);
+
+        json.beginMember("__data__");
+        char *pngBuffer;
+        int pngBufferSize;
+        Image::writePixelsToBuffer(pixels, width, height, channels, false, &pngBuffer, &pngBufferSize);
+        //std::cerr <<" Before = "<<(width * height * channels * sizeof *pixels)
+        //          <<", after = "<<pngBufferSize << ", ratio = " << double(width * height * channels * sizeof *pixels)/pngBufferSize;
+        json.writeBase64(pngBuffer, pngBufferSize);
+        free(pngBuffer);
+        json.endMember(); // __data__
+
+        delete [] pixels;
+        json.endObject();
+    }
+}
+
+
+static inline GLuint
+downsampledFramebuffer(GLuint oldFbo, GLint drawbuffer,
+                       GLint colorRb, GLint depthRb, GLint stencilRb,
+                       GLuint *rbs, GLint *numRbs)
+{
+    GLuint fbo;
+    GLint format;
+    GLint w, h;
+
+    *numRbs = 0;
+
+    glGenFramebuffers(1, &fbo);
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+    glBindRenderbuffer(GL_RENDERBUFFER, colorRb);
+    glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+                                 GL_RENDERBUFFER_WIDTH, &w);
+    glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+                                 GL_RENDERBUFFER_HEIGHT, &h);
+    glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+                                 GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
+
+    glGenRenderbuffers(1, &rbs[*numRbs]);
+    glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
+    glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
+    glFramebufferRenderbuffer(GL_FRAMEBUFFER, drawbuffer,
+                              GL_RENDERBUFFER, rbs[*numRbs]);
+
+    glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
+    glDrawBuffer(drawbuffer);
+    glReadBuffer(drawbuffer);
+    glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
+                      GL_COLOR_BUFFER_BIT, GL_NEAREST);
+    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+    ++*numRbs;
+
+    if (stencilRb == depthRb && stencilRb) {
+        //combined depth and stencil buffer
+        glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
+        glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+                                     GL_RENDERBUFFER_WIDTH, &w);
+        glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+                                     GL_RENDERBUFFER_HEIGHT, &h);
+        glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+                                     GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
+
+        glGenRenderbuffers(1, &rbs[*numRbs]);
+        glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
+        glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+                                  GL_RENDERBUFFER, rbs[*numRbs]);
+        glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
+        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
+        glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
+                          GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
+        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+        ++*numRbs;
+    } else {
+        if (depthRb) {
+            glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
+            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+                                         GL_RENDERBUFFER_WIDTH, &w);
+            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+                                         GL_RENDERBUFFER_HEIGHT, &h);
+            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+                                         GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
+
+            glGenRenderbuffers(1, &rbs[*numRbs]);
+            glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
+            glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
+            glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+                                      GL_DEPTH_ATTACHMENT,
+                                      GL_RENDERBUFFER, rbs[*numRbs]);
+            glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
+            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
+            glDrawBuffer(GL_DEPTH_ATTACHMENT);
+            glReadBuffer(GL_DEPTH_ATTACHMENT);
+            glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
+                              GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+            ++*numRbs;
+        }
+        if (stencilRb) {
+            glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);
+            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+                                         GL_RENDERBUFFER_WIDTH, &w);
+            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+                                         GL_RENDERBUFFER_HEIGHT, &h);
+            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+                                     GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
+
+            glGenRenderbuffers(1, &rbs[*numRbs]);
+            glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
+            glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
+            glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+                                      GL_STENCIL_ATTACHMENT,
+                                      GL_RENDERBUFFER, rbs[*numRbs]);
+            glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
+            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
+            glDrawBuffer(GL_STENCIL_ATTACHMENT);
+            glReadBuffer(GL_STENCIL_ATTACHMENT);
+            glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
+                              GL_STENCIL_BUFFER_BIT, GL_NEAREST);
+            ++*numRbs;
+        }
+    }
+
+    return fbo;
+}
+
+
+static void
+dumpDrawBuffers(JSONWriter &json, GLboolean dumpDepth, GLboolean dumpStencil)
+{
+    json.beginMember("GL_RGBA");
+    dumpDrawBufferImage(json, GL_RGBA);
+    json.endMember();
+
+    if (dumpDepth) {
+        json.beginMember("GL_DEPTH_COMPONENT");
+        dumpDrawBufferImage(json, GL_DEPTH_COMPONENT);
+        json.endMember();
+    }
+
+    if (dumpStencil) {
+        json.beginMember("GL_STENCIL_INDEX");
+        dumpDrawBufferImage(json, GL_STENCIL_INDEX);
+        json.endMember();
+    }
+}
+
+
+static void
+dumpFramebuffer(JSONWriter &json)
+{
+    json.beginMember("framebuffer");
+    json.beginObject();
+
+    GLint boundDrawFbo = 0, boundReadFbo = 0;
+    glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundDrawFbo);
+    glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundReadFbo);
+    if (!boundDrawFbo) {
+        GLint depth_bits = 0;
+        glGetIntegerv(GL_DEPTH_BITS, &depth_bits);
+        GLint stencil_bits = 0;
+        glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
+        dumpDrawBuffers(json, depth_bits, stencil_bits);
+    } else {
+        GLint colorRb, stencilRb, depthRb;
+        GLint boundRb;
+        glGetIntegerv(GL_RENDERBUFFER_BINDING, &boundRb);
+        GLint drawbuffer = GL_NONE;
+        glGetIntegerv(GL_DRAW_BUFFER, &drawbuffer);
+
+        glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
+                                              drawbuffer,
+                                              GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
+                                              &colorRb);
+        glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
+                                              GL_DEPTH_ATTACHMENT,
+                                              GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
+                                              &depthRb);
+        glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
+                                              GL_STENCIL_ATTACHMENT,
+                                              GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
+                                              &stencilRb);
+
+        GLint colorSamples, depthSamples, stencilSamples;
+        GLuint rbs[3];
+        GLint numRbs = 0;
+        GLuint fboCopy = 0;
+        glBindRenderbuffer(GL_RENDERBUFFER, colorRb);
+        glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+                                     GL_RENDERBUFFER_SAMPLES, &colorSamples);
+        glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
+        glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+                                     GL_RENDERBUFFER_SAMPLES, &depthSamples);
+        glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);
+        glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+                                     GL_RENDERBUFFER_SAMPLES, &stencilSamples);
+        glBindRenderbuffer(GL_RENDERBUFFER, boundRb);
+
+        if (colorSamples || depthSamples || stencilSamples) {
+            //glReadPixels doesnt support multisampled buffers so we need
+            // to blit the fbo to a temporary one
+            fboCopy = downsampledFramebuffer(boundDrawFbo, drawbuffer,
+                                             colorRb, depthRb, stencilRb,
+                                             rbs, &numRbs);
+        }
+        glDrawBuffer(drawbuffer);
+        glReadBuffer(drawbuffer);
+
+        dumpDrawBuffers(json, depthRb, stencilRb);
+
+        if (fboCopy) {
+            glBindFramebuffer(GL_FRAMEBUFFER, boundDrawFbo);
+            glBindFramebuffer(GL_READ_FRAMEBUFFER, boundReadFbo);
+            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, boundDrawFbo);
+            glBindRenderbuffer(GL_RENDERBUFFER_BINDING, boundRb);
+            glDeleteRenderbuffers(numRbs, rbs);
+            glDeleteFramebuffers(1, &fboCopy);
+        }
+    }
+
+    json.endObject();
+    json.endMember(); // framebuffer
+}
+
+
+void dumpCurrentContext(std::ostream &os)
+{
+    JSONWriter json(os);
+    dumpParameters(json);
+    dumpShaders(json);
+    dumpTextures(json);
+    dumpFramebuffer(json);
+}
+
+
+} /* namespace glstate */
index 1342629084f8d01bc444d1ba536924037350e295..abbfad00ffaccf43901b52ee451545f636f8acca 100644 (file)
 
 #include <ostream>
 
+#include "glimports.hpp"
+
+
+class JSONWriter;
+
 
 namespace glstate {
 
 
-void state_dump(std::ostream &os);
+const char *enumToString(GLenum pname);
+
+void dumpEnum(JSONWriter &json, GLenum pname);
+
+void dumpParameters(JSONWriter &json);
+
+void dumpCurrentContext(std::ostream &os);
 
 
-} /* namespace glretrace */
+} /* namespace glstate */
 
 
 #endif /* _GLSTATE_HPP_ */
index 859b3df189180f49c93fe68c8d4d0e9d01efb552..38084151979f6ad62aaed2381efc687b1738cfaa 100644 (file)
@@ -197,7 +197,7 @@ class JsonWriter(Visitor):
 
     def visit_enum(self, enum, instance):
         if enum.expr == 'GLenum':
-            print '    writeEnum(json, %s);' % instance
+            print '    dumpEnum(json, %s);' % instance
         else:
             print '    json.writeNumber(%s);' % instance
 
@@ -232,19 +232,17 @@ class StateDumper:
 
     def dump(self):
         print '#include <string.h>'
-        print '#include <iostream>'
-        print '#include <algorithm>'
         print
-        print '#include "image.hpp"'
         print '#include "json.hpp"'
-        print '#include "glimports.hpp"'
         print '#include "glproc.hpp"'
         print '#include "glsize.hpp"'
         print '#include "glstate.hpp"'
         print
+        print 'namespace glstate {'
+        print
 
-        print 'static const char *'
-        print '_enum_string(GLenum pname)'
+        print 'const char *'
+        print 'enumToString(GLenum pname)'
         print '{'
         print '    switch(pname) {'
         for name in GLenum.values:
@@ -256,24 +254,10 @@ class StateDumper:
         print '}'
         print
 
-        print 'static const char *'
-        print 'enum_string(GLenum pname)'
+        print 'void'
+        print 'dumpEnum(JSONWriter &json, GLenum pname)'
         print '{'
-        print '    const char *s = _enum_string(pname);'
-        print '    if (s) {'
-        print '        return s;'
-        print '    } else {'
-        print '        static char buf[16];'
-        print '        snprintf(buf, sizeof buf, "0x%04x", pname);'
-        print '        return buf;'
-        print '    }'
-        print '}'
-        print
-
-        print 'static inline void'
-        print 'writeEnum(JSONWriter &json, GLenum pname)'
-        print '{'
-        print '    const char *s = _enum_string(pname);'
+        print '    const char *s = enumToString(pname);'
         print '    if (s) {'
         print '        json.writeString(s);'
         print '    } else {'
@@ -282,492 +266,8 @@ class StateDumper:
         print '}'
         print
 
-        # shaders
-        print '''
-static void
-writeShader(JSONWriter &json, GLuint shader)
-{
-    if (!shader) {
-        return;
-    }
-
-    GLint shader_type = 0;
-    glGetShaderiv(shader, GL_SHADER_TYPE, &shader_type);
-    if (!shader_type) {
-        return;
-    }
-
-    GLint source_length = 0;
-    glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &source_length);
-    if (!source_length) {
-        return;
-    }
-
-    GLchar *source = new GLchar[source_length];
-    GLsizei length = 0;
-    source[0] = 0;
-    glGetShaderSource(shader, source_length, &length, source);
-
-    json.beginMember(enum_string(shader_type));
-    json.writeString(source);
-    json.endMember();
-
-    delete [] source;
-}
-
-static void
-writeShaderObj(JSONWriter &json, GLhandleARB shaderObj)
-{
-    if (!shaderObj) {
-        return;
-    }
-
-    GLint shader_type = 0;
-    glGetObjectParameterivARB(shaderObj, GL_OBJECT_TYPE_ARB, &shader_type);
-    if (!shader_type) {
-        return;
-    }
-
-    GLint source_length = 0;
-    glGetObjectParameterivARB(shaderObj, GL_OBJECT_SHADER_SOURCE_LENGTH_ARB, &source_length);
-    if (!source_length) {
-        return;
-    }
-
-    GLcharARB *source = new GLcharARB[source_length];
-    GLsizei length = 0;
-    source[0] = 0;
-    glGetShaderSource(shaderObj, source_length, &length, source);
-
-    json.beginMember(enum_string(shader_type));
-    json.writeString(source);
-    json.endMember();
-
-    delete [] source;
-}
-
-static inline void
-writeCurrentProgram(JSONWriter &json)
-{
-    GLint program = 0;
-    glGetIntegerv(GL_CURRENT_PROGRAM, &program);
-    if (!program) {
-        return;
-    }
-
-    GLint attached_shaders = 0;
-    glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
-    if (!attached_shaders) {
-        return;
-    }
-
-    GLuint *shaders = new GLuint[attached_shaders];
-    GLsizei count = 0;
-    glGetAttachedShaders(program, attached_shaders, &count, shaders);
-    for (GLsizei i = 0; i < count; ++ i) {
-       writeShader(json, shaders[i]);
-    }
-    delete [] shaders;
-}
-
-static inline void
-writeCurrentProgramObj(JSONWriter &json)
-{
-    GLhandleARB programObj = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
-    if (!programObj) {
-        return;
-    }
-
-    GLint attached_shaders = 0;
-    glGetProgramivARB(programObj, GL_OBJECT_ATTACHED_OBJECTS_ARB, &attached_shaders);
-    if (!attached_shaders) {
-        return;
-    }
-
-    GLhandleARB *shaderObjs = new GLhandleARB[attached_shaders];
-    GLsizei count = 0;
-    glGetAttachedObjectsARB(programObj, attached_shaders, &count, shaderObjs);
-    for (GLsizei i = 0; i < count; ++ i) {
-       writeShaderObj(json, shaderObjs[i]);
-    }
-    delete [] shaderObjs;
-}
-
-static inline void
-writeArbProgram(JSONWriter &json, GLenum target)
-{
-    if (!glIsEnabled(target)) {
-        return;
-    }
-
-    GLint program_length = 0;
-    glGetProgramivARB(target, GL_PROGRAM_LENGTH_ARB, &program_length);
-    if (!program_length) {
-        return;
-    }
-
-    GLchar *source = new GLchar[program_length + 1];
-    source[0] = 0;
-    glGetProgramStringARB(target, GL_PROGRAM_STRING_ARB, source);
-    source[program_length] = 0;
-
-    json.beginMember(enum_string(target));
-    json.writeString(source);
-    json.endMember();
-
-    delete [] source;
-}
-'''
-
-        # texture image
-        print '''
-static inline void
-writeTextureImage(JSONWriter &json, GLenum target, GLint level)
-{
-    GLint width, height = 1, depth = 1;
-
-    width = 0;
-    glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
-
-    if (target != GL_TEXTURE_1D) {
-        height = 0;
-        glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
-        if (target == GL_TEXTURE_3D) {
-            depth = 0;
-            glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth);
-        }
-    }
-
-    if (width <= 0 || height <= 0 || depth <= 0) {
-        return;
-    } else {
-        char label[512];
-
-        GLint active_texture = GL_TEXTURE0;
-        glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
-        snprintf(label, sizeof label, "%s, %s, level = %i", _enum_string(active_texture), _enum_string(target), level);
-
-        json.beginMember(label);
-
-        json.beginObject();
-
-        // Tell the GUI this is no ordinary object, but an image
-        json.writeStringMember("__class__", "image");
-
-        json.writeNumberMember("__width__", width);
-        json.writeNumberMember("__height__", height);
-        json.writeNumberMember("__depth__", depth);
-
-        // Hardcoded for now, but we could chose types more adequate to the
-        // texture internal format
-        json.writeStringMember("__type__", "uint8");
-        json.writeBoolMember("__normalized__", true);
-        json.writeNumberMember("__channels__", 4);
-        
-        GLubyte *pixels = new GLubyte[depth*width*height*4];
-
-        glGetTexImage(target, level, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
-
-        json.beginMember("__data__");
-        char *pngBuffer;
-        int pngBufferSize;
-        Image::writePixelsToBuffer(pixels, width, height, 4, false, &pngBuffer, &pngBufferSize);
-        json.writeBase64(pngBuffer, pngBufferSize);
-        free(pngBuffer);
-        json.endMember(); // __data__
-
-        delete [] pixels;
-        json.endObject();
-    }
-}
-
-
-static bool
-getDrawableBounds(GLint *width, GLint *height) {
-#if defined(_WIN32)
-
-    HDC hDC = wglGetCurrentDC();
-    if (!hDC) {
-        return false;
-    }
-
-    HWND hWnd = WindowFromDC(hDC);
-    RECT rect;
-
-    if (!GetClientRect(hWnd, &rect)) {
-       return false;
-    }
-
-    *width  = rect.right  - rect.left;
-    *height = rect.bottom - rect.top;
-
-#elif 0 /* __APPLE__ */
-
-    CGLError CGLGetSurface(CGLContextObj, CGSConnectionID*, CGSWindowID*, CGSSurfaceID*);
-    CGError CGSGetWindowBounds(CGSConnectionID, CGWindowID, CGRect *ret);
-
-#else
-
-    Display *display;
-    Drawable drawable;
-    Window root;
-    int x, y;
-    unsigned int w, h, bw, depth;
-
-    display = glXGetCurrentDisplay();
-    if (!display) {
-        return false;
-    }
-
-    drawable = glXGetCurrentDrawable();
-    if (drawable == None) {
-        return false;
-    }
-
-    if (!XGetGeometry(display, drawable, &root, &x, &y, &w, &h, &bw, &depth)) {
-        return false;
-    }
-
-    *width = w;
-    *height = h;
-
-#endif
-
-    return true;
-}
-
-
-static inline void
-writeDrawBufferImage(JSONWriter &json, GLenum format)
-{
-    GLint channels = __gl_format_channels(format);
-
-    GLint width, height;
-
-    if (!getDrawableBounds(&width, &height)) {
-        json.writeNull();
-    } else {
-        json.beginObject();
-
-        // Tell the GUI this is no ordinary object, but an image
-        json.writeStringMember("__class__", "image");
-
-        json.writeNumberMember("__width__", width);
-        json.writeNumberMember("__height__", height);
-        json.writeNumberMember("__depth__", 1);
-
-        // Hardcoded for now, but we could chose types more adequate to the
-        // texture internal format
-        json.writeStringMember("__type__", "uint8");
-        json.writeBoolMember("__normalized__", true);
-        json.writeNumberMember("__channels__", channels);
-
-        GLubyte *pixels = new GLubyte[width*height*channels];
-        
-        GLint drawbuffer = GL_NONE;
-        GLint readbuffer = GL_NONE;
-        glGetIntegerv(GL_DRAW_BUFFER, &drawbuffer);
-        glGetIntegerv(GL_READ_BUFFER, &readbuffer);
-        glReadBuffer(drawbuffer);
-
-        glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
-        glPixelStorei(GL_PACK_ALIGNMENT, 1);
-
-        glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, pixels);
-
-        glPopClientAttrib();
-        glReadBuffer(readbuffer);
-
-        json.beginMember("__data__");
-        char *pngBuffer;
-        int pngBufferSize;
-        Image::writePixelsToBuffer(pixels, width, height, channels, false, &pngBuffer, &pngBufferSize);
-        //std::cerr <<" Before = "<<(width * height * channels * sizeof *pixels)
-        //          <<", after = "<<pngBufferSize << ", ratio = " << double(width * height * channels * sizeof *pixels)/pngBufferSize;
-        json.writeBase64(pngBuffer, pngBufferSize);
-        free(pngBuffer);
-        json.endMember(); // __data__
-
-        delete [] pixels;
-        json.endObject();
-    }
-}
-
-static inline GLuint
-downsampledFramebuffer(GLuint oldFbo, GLint drawbuffer,
-                       GLint colorRb, GLint depthRb, GLint stencilRb,
-                       GLuint *rbs, GLint *numRbs)
-{
-    GLuint fbo;
-    GLint format;
-    GLint w, h;
-
-    *numRbs = 0;
-
-    glGenFramebuffers(1, &fbo);
-    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-
-    glBindRenderbuffer(GL_RENDERBUFFER, colorRb);
-    glGetRenderbufferParameteriv(GL_RENDERBUFFER,
-                                 GL_RENDERBUFFER_WIDTH, &w);
-    glGetRenderbufferParameteriv(GL_RENDERBUFFER,
-                                 GL_RENDERBUFFER_HEIGHT, &h);
-    glGetRenderbufferParameteriv(GL_RENDERBUFFER,
-                                 GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
-
-    glGenRenderbuffers(1, &rbs[*numRbs]);
-    glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
-    glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
-    glFramebufferRenderbuffer(GL_FRAMEBUFFER, drawbuffer,
-                              GL_RENDERBUFFER, rbs[*numRbs]);
-
-    glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
-    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
-    glDrawBuffer(drawbuffer);
-    glReadBuffer(drawbuffer);
-    glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
-                      GL_COLOR_BUFFER_BIT, GL_NEAREST);
-    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-    ++*numRbs;
-
-    if (stencilRb == depthRb && stencilRb) {
-        //combined depth and stencil buffer
-        glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
-        glGetRenderbufferParameteriv(GL_RENDERBUFFER,
-                                     GL_RENDERBUFFER_WIDTH, &w);
-        glGetRenderbufferParameteriv(GL_RENDERBUFFER,
-                                     GL_RENDERBUFFER_HEIGHT, &h);
-        glGetRenderbufferParameteriv(GL_RENDERBUFFER,
-                                     GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
-
-        glGenRenderbuffers(1, &rbs[*numRbs]);
-        glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
-        glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
-        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
-                                  GL_RENDERBUFFER, rbs[*numRbs]);
-        glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
-        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
-        glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
-                          GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
-        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-        ++*numRbs;
-    } else {
-        if (depthRb) {
-            glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
-            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
-                                         GL_RENDERBUFFER_WIDTH, &w);
-            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
-                                         GL_RENDERBUFFER_HEIGHT, &h);
-            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
-                                         GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
-
-            glGenRenderbuffers(1, &rbs[*numRbs]);
-            glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
-            glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
-            glFramebufferRenderbuffer(GL_FRAMEBUFFER,
-                                      GL_DEPTH_ATTACHMENT,
-                                      GL_RENDERBUFFER, rbs[*numRbs]);
-            glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
-            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
-            glDrawBuffer(GL_DEPTH_ATTACHMENT);
-            glReadBuffer(GL_DEPTH_ATTACHMENT);
-            glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
-                              GL_DEPTH_BUFFER_BIT, GL_NEAREST);
-            ++*numRbs;
-        }
-        if (stencilRb) {
-            glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);
-            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
-                                         GL_RENDERBUFFER_WIDTH, &w);
-            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
-                                         GL_RENDERBUFFER_HEIGHT, &h);
-            glGetRenderbufferParameteriv(GL_RENDERBUFFER,
-                                     GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
-
-            glGenRenderbuffers(1, &rbs[*numRbs]);
-            glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
-            glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
-            glFramebufferRenderbuffer(GL_FRAMEBUFFER,
-                                      GL_STENCIL_ATTACHMENT,
-                                      GL_RENDERBUFFER, rbs[*numRbs]);
-            glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
-            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
-            glDrawBuffer(GL_STENCIL_ATTACHMENT);
-            glReadBuffer(GL_STENCIL_ATTACHMENT);
-            glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
-                              GL_STENCIL_BUFFER_BIT, GL_NEAREST);
-            ++*numRbs;
-        }
-    }
-
-    return fbo;
-}
-
-static void
-writeDrawBuffers(JSONWriter &json, GLboolean writeDepth, GLboolean writeStencil)
-{
-    json.beginMember("GL_RGBA");
-    writeDrawBufferImage(json, GL_RGBA);
-    json.endMember();
-
-    if (writeDepth) {
-        json.beginMember("GL_DEPTH_COMPONENT");
-        writeDrawBufferImage(json, GL_DEPTH_COMPONENT);
-        json.endMember();
-    }
-
-    if (writeStencil) {
-        json.beginMember("GL_STENCIL_INDEX");
-        writeDrawBufferImage(json, GL_STENCIL_INDEX);
-        json.endMember();
-    }
-}
-
-'''
-
-        # textures
-        print 'static inline void'
-        print 'writeTexture(JSONWriter &json, GLenum target, GLenum binding)'
-        print '{'
-        print '    GLint texture_binding = 0;'
-        print '    glGetIntegerv(binding, &texture_binding);'
-        print '    if (!glIsEnabled(target) && !texture_binding) {'
-        print '        return;'
-        print '    }'
-        print
-        print '    GLint level = 0;'
-        print '    do {'
-        print '        GLint width = 0, height = 0;'
-        print '        glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);'
-        print '        glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);'
-        print '        if (!width || !height) {'
-        print '            break;'
-        print '        }'
-        print
-        print '        if (target == GL_TEXTURE_CUBE_MAP) {'
-        print '            for (int face = 0; face < 6; ++face) {'
-        print '                writeTextureImage(json, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level);'
-        print '            }'
-        print '        } else {'
-        print '            writeTextureImage(json, target, level);'
-        print '        }'
-        print
-        print '        ++level;'
-        print '    } while(true);'
-        print '}'
-        print
-
-        print 'void glstate::state_dump(std::ostream &os)'
+        print 'void dumpParameters(JSONWriter &json)'
         print '{'
-        print '    JSONWriter json(os);'
-        self.dump_parameters()
-        self.dump_current_program()
-        self.dump_textures()
-        self.dump_framebuffer()
-        print '}'
-        print
-
-    def dump_parameters(self):
         print '    json.beginMember("parameters");'
         print '    json.beginObject();'
         
@@ -782,7 +282,10 @@ writeDrawBuffers(JSONWriter &json, GLboolean writeDepth, GLboolean writeStencil)
 
         print '    json.endObject();'
         print '    json.endMember(); // parameters'
+        print '}'
         print
+        
+        print '} /*namespace glstate */'
 
     def dump_material_params(self):
         for face in ['GL_FRONT', 'GL_BACK']:
@@ -887,114 +390,6 @@ writeDrawBuffers(JSONWriter &json, GLboolean writeDepth, GLboolean writeStencil)
         print '    }'
         print
 
-    def dump_current_program(self):
-        print '    json.beginMember("shaders");'
-        print '    json.beginObject();'
-        print '    writeCurrentProgram(json);'
-        for target in self.program_targets:
-            print '    writeArbProgram(json, %s);' % target
-        print '    json.endObject();'
-        print '    json.endMember(); //shaders'
-        print
-
-    def dump_textures(self):
-        print '    {'
-        print '        json.beginMember("textures");'
-        print '        json.beginObject();'
-        print '        GLint active_texture = GL_TEXTURE0;'
-        print '        glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);'
-        print '        GLint max_texture_coords = 0;'
-        print '        glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);'
-        print '        GLint max_combined_texture_image_units = 0;'
-        print '        glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_combined_texture_image_units);'
-        print '        GLint max_units = std::max(max_combined_texture_image_units, max_texture_coords);'
-        print '        for (GLint unit = 0; unit < max_units; ++unit) {'
-        print '            GLenum texture = GL_TEXTURE0 + unit;'
-        print '            glActiveTexture(texture);'
-        for target, binding in texture_targets:
-            print '            writeTexture(json, %s, %s);' % (target, binding)
-        print '        }'
-        print '        glActiveTexture(active_texture);'
-        print '        json.endObject();'
-        print '        json.endMember(); // textures'
-        print '    }'
-        print
-
-    def dump_framebuffer(self):
-        print '    json.beginMember("framebuffer");'
-        print '    json.beginObject();'
-        # TODO: Handle real FBOs
-        print
-        print '    GLint boundDrawFbo = 0, boundReadFbo = 0;'
-        print '    glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundDrawFbo);'
-        print '    glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundReadFbo);'
-        print '    if (!boundDrawFbo) {'
-        print '        GLint depth_bits = 0;'
-        print '        glGetIntegerv(GL_DEPTH_BITS, &depth_bits);'
-        print '        GLint stencil_bits = 0;'
-        print '        glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);'
-        print '        writeDrawBuffers(json, depth_bits, stencil_bits);'
-        print '    } else {'
-        print '        GLint colorRb, stencilRb, depthRb;'
-        print '        GLint boundRb;'
-        print '        glGetIntegerv(GL_RENDERBUFFER_BINDING, &boundRb);'
-        print '        GLint drawbuffer = GL_NONE;'
-        print '        glGetIntegerv(GL_DRAW_BUFFER, &drawbuffer);'
-        print
-        print '        glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,'
-        print '                                              drawbuffer,'
-        print '                                              GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,'
-        print '                                              &colorRb);'
-        print '        glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,'
-        print '                                              GL_DEPTH_ATTACHMENT,'
-        print '                                              GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,'
-        print '                                              &depthRb);'
-        print '        glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,'
-        print '                                              GL_STENCIL_ATTACHMENT,'
-        print '                                              GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,'
-        print '                                              &stencilRb);'
-        print
-        print '        GLint colorSamples, depthSamples, stencilSamples;'
-        print '        GLuint rbs[3];'
-        print '        GLint numRbs = 0;'
-        print '        GLuint fboCopy = 0;'
-        print '        glBindRenderbuffer(GL_RENDERBUFFER, colorRb);'
-        print '        glGetRenderbufferParameteriv(GL_RENDERBUFFER,'
-        print '                                     GL_RENDERBUFFER_SAMPLES, &colorSamples);'
-        print '        glBindRenderbuffer(GL_RENDERBUFFER, depthRb);'
-        print '        glGetRenderbufferParameteriv(GL_RENDERBUFFER,'
-        print '                                     GL_RENDERBUFFER_SAMPLES, &depthSamples);'
-        print '        glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);'
-        print '        glGetRenderbufferParameteriv(GL_RENDERBUFFER,'
-        print '                                     GL_RENDERBUFFER_SAMPLES, &stencilSamples);'
-        print '        glBindRenderbuffer(GL_RENDERBUFFER, boundRb);'
-        print
-        print '        if (colorSamples || depthSamples || stencilSamples) {'
-        print '            //glReadPixels doesnt support multisampled buffers so we need'
-        print '            // to blit the fbo to a temporary one'
-        print '            fboCopy = downsampledFramebuffer(boundDrawFbo, drawbuffer,'
-        print '                                             colorRb, depthRb, stencilRb,'
-        print '                                             rbs, &numRbs);'
-        print '        }'
-        print '        glDrawBuffer(drawbuffer);'
-        print '        glReadBuffer(drawbuffer);'
-        print
-        print '        writeDrawBuffers(json, depthRb, stencilRb);'
-        print
-        print '        if (fboCopy) {'
-        print '            glBindFramebuffer(GL_FRAMEBUFFER, boundDrawFbo);'
-        print '            glBindFramebuffer(GL_READ_FRAMEBUFFER, boundReadFbo);'
-        print '            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, boundDrawFbo);'
-        print '            glBindRenderbuffer(GL_RENDERBUFFER_BINDING, boundRb);'
-        print '            glDeleteRenderbuffers(numRbs, rbs);'
-        print '            glDeleteFramebuffers(1, &fboCopy);'
-        print '        }'
-        print '    }'
-        print
-        print '    json.endObject();'
-        print '    json.endMember(); // framebuffer'
-        pass
-
     def dump_atoms(self, getter, *args):
         for function, type, count, name in parameters:
             inflection = getter.inflector.radical + getter.suffix