[PATCH 3/3][RFC] Add gl state rebuilding code for single frame capture

Juha-Pekka Heikkila juhapekka.heikkila at gmail.com
Mon Mar 2 04:13:28 PST 2015


First attempt on gl state rebuilding. glxgears works as poc
with these changes when start capture while glxgears is already
running.

Signed-off-by: Juha-Pekka Heikkila <juhapekka.heikkila at gmail.com>
---
 wrappers/egltrace.py |   8 ++++
 wrappers/glxtrace.py | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 132 insertions(+)

diff --git a/wrappers/egltrace.py b/wrappers/egltrace.py
index 9ce62b3..a08dbf0 100644
--- a/wrappers/egltrace.py
+++ b/wrappers/egltrace.py
@@ -251,4 +251,12 @@ void APIENTRY glWeightPointerOESBounds(GLint size, GLenum type, GLsizei stride,
 #endif /* ANDROID */
 
 
+/*
+ * FIXME
+ * dummy. maybe fill in later.
+ */
+extern "C" void stateRebuild(void) {
+   return;
+}
+
 '''
diff --git a/wrappers/glxtrace.py b/wrappers/glxtrace.py
index e9c43a9..e8a181f 100644
--- a/wrappers/glxtrace.py
+++ b/wrappers/glxtrace.py
@@ -225,5 +225,129 @@ void * dlopen(const char *filename, int flag)
 }
 
 
+/*
+ * For rebuilding gl state in single frame capture mode.
+ */
+extern "C" void stateRebuild(void) {
+    /*
+     * viewport set always
+     */
+    GLint viewPort[4];
+    _glGetIntegerv(GL_VIEWPORT, (GLint*)&viewPort);
+    glViewport(viewPort[0], viewPort[1], viewPort[2], viewPort[3]);
+
+    GLint scissorBox[4];
+    _glGetIntegerv(GL_SCISSOR_BOX, (GLint*)&scissorBox);
+    if (memcmp((void*)&viewPort, (void*)&scissorBox, sizeof(viewPort)) != 0)
+        glScissor(scissorBox[0], scissorBox[1], scissorBox[2], scissorBox[3]);
+
+    /*
+     * Enable/Disable parameters
+     */
+    const GLenum simpleParams[] = {
+        GL_SCISSOR_TEST, GL_CULL_FACE, GL_DEPTH_TEST, GL_LIGHTING,
+        GL_NORMALIZE
+    };
+
+    for (int c = 0; c < sizeof(simpleParams)/sizeof(simpleParams[0]); c++) {
+        if (_glIsEnabled(simpleParams[c]) == GL_TRUE)
+            glEnable(simpleParams[c]);
+    }
+
+    /*
+     * Simple Lights
+     */
+    const struct {
+        GLenum  lightType;
+        int     paramAmount; /* max 4 */
+        GLfloat params0[4];  /* silly light 0 special case */
+        GLfloat paramsn[4];  /* all the other lights */
+    } lightTypes[] = {
+        { GL_AMBIENT, 4, {0, 0, 0, 1}, {0, 0, 0, 1} },
+        { GL_DIFFUSE, 4, {1, 1, 1, 1}, {0, 0, 0, 1} },
+        { GL_SPECULAR, 4, {1, 1, 1, 1}, {0, 0, 0, 1} },
+        { GL_POSITION, 4, {0, 0, 1, 0}, {0, 0, 1, 0} },
+        { GL_SPOT_DIRECTION, 3, {0, 0, -1, 0}, {0, 0, -1, 0} },
+        { GL_SPOT_EXPONENT, 1, {0, 0, 0, 0}, {0, 0, 0, 0} },
+        { GL_SPOT_CUTOFF, 1, {180, 0, 0, 0}, {180, 0, 0, 0} },
+        { GL_CONSTANT_ATTENUATION, 1, {1, 0, 0, 0}, {1, 0, 0, 0} },
+        { GL_LINEAR_ATTENUATION, 1, {0, 0, 0, 0}, {0, 0, 0, 0} },
+        { GL_QUADRATIC_ATTENUATION, 1, {0, 0, 0, 0}, {0, 0, 0, 0} }
+    };
+
+    unsigned c_max;
+    _glGetIntegerv(GL_MAX_LIGHTS, (GLint*)&c_max);
+
+    for (unsigned c = 0; c < c_max; c++) {
+        if (_glIsEnabled(GL_LIGHT0+c) == GL_TRUE)
+            glEnable(GL_LIGHT0+c);
+
+        GLfloat lightRVals[4];
+
+        for (unsigned c2 = 0; c2 < sizeof(lightTypes)/sizeof(lightTypes[0]);
+             c2++) {
+
+            _glGetLightfv(GL_LIGHT0+c, lightTypes[c2].lightType,
+                         (GLfloat*)&lightRVals );
+
+            /*
+             * light 0 special case
+             */
+            if (c == 0) {
+                if (memcmp((void*)&lightRVals, (void*)&lightTypes[c2].params0,
+                           sizeof(GLfloat)*lightTypes[c2].paramAmount) != 0)
+                    glLightfv(GL_LIGHT0,lightTypes[c2].lightType,
+                              (GLfloat*)&lightRVals );
+            }
+            else {
+                if (memcmp((void*)&lightRVals, (void*)&lightTypes[c2].paramsn,
+                           sizeof(GLfloat)*lightTypes[c2].paramAmount) != 0)
+                    glLightfv(GL_LIGHT0+c,lightTypes[c2].lightType,
+                              (GLfloat*)&lightRVals );
+            }
+        }
+    }
+
+    GLint cullMode;
+    _glGetIntegerv(GL_CULL_FACE_MODE, (GLint*)&cullMode);
+    if (cullMode != GL_BACK)
+        glCullFace(cullMode);
+
+    /*
+     * matrixes
+     */
+    GLint matrixMode, matrixMode2; /* will be used to set final matrix mode */
+    GLfloat matrix[16];
+    const GLfloat iMatrix[16] = {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1};
+    const struct {
+        GLenum matrixname;
+        GLenum modename;
+        GLenum stackdepth;
+    } matrixList[] = {
+        { GL_PROJECTION_MATRIX, GL_PROJECTION, GL_PROJECTION_STACK_DEPTH },
+        { GL_TEXTURE_MATRIX, GL_TEXTURE, GL_TEXTURE_STACK_DEPTH },
+        { GL_COLOR_MATRIX, GL_COLOR, GL_COLOR_MATRIX_STACK_DEPTH },
+        { GL_MODELVIEW_MATRIX, GL_MODELVIEW, GL_MODELVIEW_STACK_DEPTH }
+    };
+
+    _glGetIntegerv(GL_MATRIX_MODE, (GLint*)&matrixMode);
+    matrixMode2 = matrixMode;
+
+    for (unsigned c = 0; c < sizeof(matrixList)/sizeof(matrixList[0]); c++) {
+        _glGetFloatv(matrixList[c].matrixname, (GLfloat*)&matrix);
+        if (memcmp((void*)&iMatrix, (void*)&matrix, sizeof(matrix)) != 0) {
+             glMatrixMode(matrixList[c].modename);
+             matrixMode2 = matrixList[c].modename;
+            glLoadMatrixf((GLfloat*)&matrix);
+        }
+
+    }
+
+    if (matrixMode != matrixMode2)
+        glMatrixMode(matrixMode);
+
+    return;
+}
+
 
 '''
-- 
1.8.5.1



More information about the apitrace mailing list