summaryrefslogtreecommitdiffstats
path: root/src/datavisualizationqml2/glstatestore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/datavisualizationqml2/glstatestore.cpp')
-rw-r--r--src/datavisualizationqml2/glstatestore.cpp377
1 files changed, 377 insertions, 0 deletions
diff --git a/src/datavisualizationqml2/glstatestore.cpp b/src/datavisualizationqml2/glstatestore.cpp
new file mode 100644
index 00000000..f053078b
--- /dev/null
+++ b/src/datavisualizationqml2/glstatestore.cpp
@@ -0,0 +1,377 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVisualization module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+#include "glstatestore_p.h"
+#include <QDebug>
+#include <QColor>
+#include <QFile>
+
+#ifdef VERBOSE_STATE_STORE
+static QFile *beforeFile = 0;
+static QFile *afterFile = 0;
+#endif
+
+GLStateStore::GLStateStore(QOpenGLContext *context, QObject *parent) :
+ QObject(parent),
+ QOpenGLFunctions(context)
+ #ifdef VERBOSE_STATE_STORE
+ , m_map(EnumToStringMap::newInstance())
+ #endif
+{
+ GLint maxVertexAttribs;
+ glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
+
+#ifdef VERBOSE_STATE_STORE
+ qDebug() << "GL_MAX_VERTEX_ATTRIBS: " << maxVertexAttribs;
+ if (!beforeFile) {
+ beforeFile = new QFile(QStringLiteral("state_before.txt"));
+ afterFile = new QFile(QStringLiteral("state_after.txt"));
+ beforeFile->open(QIODevice::WriteOnly);
+ afterFile->open(QIODevice::WriteOnly);
+ QDebug beforeInit(beforeFile);
+ QDebug afterInit(afterFile);
+ beforeInit << "GL states before 'context switch'" << endl;
+ afterInit << "GL states after 'context switch'" << endl;
+ }
+#endif
+
+ m_maxVertexAttribs = qMin(maxVertexAttribs, 2); // Datavis only uses 2 attribs max
+ m_vertexAttribArrayEnabledStates = new GLint[maxVertexAttribs];
+ m_vertexAttribArrayBoundBuffers = new GLint[maxVertexAttribs];
+ m_vertexAttribArraySizes = new GLint[maxVertexAttribs];
+ m_vertexAttribArrayTypes = new GLint[maxVertexAttribs];
+ m_vertexAttribArrayNormalized = new GLint[maxVertexAttribs];
+ m_vertexAttribArrayStrides = new GLint[maxVertexAttribs];
+ m_vertexAttribArrayOffsets = new GLint[maxVertexAttribs];
+
+ initGLDefaultState();
+}
+
+GLStateStore::~GLStateStore()
+{
+#ifdef VERBOSE_STATE_STORE
+ EnumToStringMap::deleteInstance();
+ m_map = 0;
+#endif
+ delete m_vertexAttribArrayEnabledStates;
+ delete m_vertexAttribArrayBoundBuffers;
+}
+
+void GLStateStore::storeGLState()
+{
+#ifdef VERBOSE_STATE_STORE
+ printCurrentState(true);
+#endif
+
+#if !defined(QT_OPENGL_ES_2)
+ glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &m_drawFramebuffer);
+ glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &m_readFramebuffer);
+#endif
+ glGetIntegerv(GL_RENDERBUFFER_BINDING, &m_renderbuffer);
+ glGetFloatv(GL_COLOR_CLEAR_VALUE, m_clearColor);
+ m_isBlendingEnabled = glIsEnabled(GL_BLEND);
+ m_isDepthTestEnabled = glIsEnabled(GL_DEPTH_TEST);
+ glGetBooleanv(GL_DEPTH_WRITEMASK, &m_isDepthWriteEnabled);
+ glGetFloatv(GL_DEPTH_CLEAR_VALUE, &m_clearDepth);
+ glGetIntegerv(GL_DEPTH_FUNC, &m_depthFunc);
+ glGetBooleanv(GL_POLYGON_OFFSET_FILL, &m_polygonOffsetFillEnabled);
+ glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &m_polygonOffsetFactor);
+ glGetFloatv(GL_POLYGON_OFFSET_UNITS, &m_polygonOffsetUnits);
+
+ glGetIntegerv(GL_CURRENT_PROGRAM, &m_currentProgram);
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &m_activeTexture);
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &m_texBinding2D);
+ glGetIntegerv(GL_FRONT_FACE, &m_frontFace);
+ m_isCullFaceEnabled = glIsEnabled(GL_CULL_FACE);
+ glGetIntegerv(GL_CULL_FACE_MODE, &m_cullFaceMode);
+ glGetIntegerv(GL_BLEND_EQUATION_RGB, &m_blendEquationRGB);
+ glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &m_blendEquationAlpha);
+ glGetIntegerv(GL_BLEND_DST_ALPHA, &m_blendDestAlpha);
+ glGetIntegerv(GL_BLEND_DST_RGB, &m_blendDestRGB);
+ glGetIntegerv(GL_BLEND_SRC_ALPHA, &m_blendSrcAlpha);
+ glGetIntegerv(GL_BLEND_SRC_RGB, &m_blendSrcRGB);
+ glGetIntegerv(GL_SCISSOR_BOX, m_scissorBox);
+ m_isScissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);
+
+ glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &m_boundArrayBuffer);
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &m_boundElementArrayBuffer);
+
+ for (int i = 0; i < m_maxVertexAttribs;i++) {
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &m_vertexAttribArrayEnabledStates[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &m_vertexAttribArrayBoundBuffers[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &m_vertexAttribArraySizes[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &m_vertexAttribArrayTypes[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &m_vertexAttribArrayNormalized[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &m_vertexAttribArrayStrides[i]);
+ }
+}
+
+#ifdef VERBOSE_STATE_STORE
+void GLStateStore::printCurrentState(bool in)
+{
+ QFile *file;
+ if (in)
+ file = beforeFile;
+ else
+ file = afterFile;
+
+ if (file->isOpen()) {
+ QDebug msg(file);
+#if !defined(QT_OPENGL_ES_2)
+ GLint drawFramebuffer;
+ GLint readFramebuffer;
+#endif
+ GLint renderbuffer;
+ GLfloat clearColor[4];
+ GLfloat clearDepth;
+ GLboolean isBlendingEnabled = glIsEnabled(GL_BLEND);
+ GLboolean isDepthTestEnabled = glIsEnabled(GL_DEPTH_TEST);
+ GLint depthFunc;
+ GLboolean isDepthWriteEnabled;
+ GLint currentProgram;
+ GLint *vertexAttribArrayEnabledStates = new GLint[m_maxVertexAttribs];
+ GLint *vertexAttribArrayBoundBuffers = new GLint[m_maxVertexAttribs];
+ GLint *vertexAttribArraySizes = new GLint[m_maxVertexAttribs];
+ GLint *vertexAttribArrayTypes = new GLint[m_maxVertexAttribs];
+ GLint *vertexAttribArrayNormalized = new GLint[m_maxVertexAttribs];
+ GLint *vertexAttribArrayStrides = new GLint[m_maxVertexAttribs];
+ GLint activeTexture;
+ GLint texBinding2D;
+ GLint arrayBufferBinding;
+ GLint frontFace;
+ GLboolean isCullFaceEnabled = glIsEnabled(GL_CULL_FACE);
+ GLint cullFaceMode;
+ GLint blendEquationRGB;
+ GLint blendEquationAlpha;
+
+ GLint blendDestAlpha;
+ GLint blendDestRGB;
+ GLint blendSrcAlpha;
+ GLint blendSrcRGB;
+ GLint scissorBox[4];
+ GLboolean isScissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);
+ GLint boundElementArrayBuffer;
+ GLboolean polygonOffsetFillEnabled;
+ GLfloat polygonOffsetFactor;
+ GLfloat polygonOffsetUnits;
+
+ glGetBooleanv(GL_DEPTH_WRITEMASK, &isDepthWriteEnabled);
+#if !defined(QT_OPENGL_ES_2)
+ glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &drawFramebuffer);
+ glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &readFramebuffer);
+#endif
+ glGetIntegerv(GL_RENDERBUFFER_BINDING, &renderbuffer);
+ glGetFloatv(GL_COLOR_CLEAR_VALUE, clearColor);
+ glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth);
+ glGetIntegerv(GL_DEPTH_FUNC, &depthFunc);
+ glGetBooleanv(GL_POLYGON_OFFSET_FILL, &polygonOffsetFillEnabled);
+ glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &polygonOffsetFactor);
+ glGetFloatv(GL_POLYGON_OFFSET_UNITS, &polygonOffsetUnits);
+
+ glGetIntegerv(GL_CURRENT_PROGRAM, &currentProgram);
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture);
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &texBinding2D );
+ glGetIntegerv(GL_FRONT_FACE, &frontFace);
+ glGetIntegerv(GL_CULL_FACE_MODE, &cullFaceMode);
+ glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
+ glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
+ glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
+ glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
+ glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
+ glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
+ glGetIntegerv(GL_SCISSOR_BOX, scissorBox);
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &boundElementArrayBuffer);
+ glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &arrayBufferBinding);
+
+ for (int i = 0; i < m_maxVertexAttribs;i++) {
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &vertexAttribArrayEnabledStates[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &vertexAttribArrayBoundBuffers[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &vertexAttribArraySizes[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &vertexAttribArrayTypes[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &vertexAttribArrayNormalized[i]);
+ glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &vertexAttribArrayStrides[i]);
+ }
+
+ QColor color;
+ color.setRgbF(clearColor[0], clearColor[1], clearColor[2]);
+ color.setAlphaF(clearColor[3]);
+
+#if !defined(QT_OPENGL_ES_2)
+ msg << "---" << endl;
+ msg << " GL_DRAW_FRAMEBUFFER_BINDING "<< drawFramebuffer << endl;
+ msg << " GL_READ_FRAMEBUFFER_BINDING "<< readFramebuffer << endl;
+#endif
+ msg << " GL_RENDERBUFFER_BINDING " << renderbuffer << endl;
+ msg << " GL_SCISSOR_TEST " << bool(isScissorTestEnabled) << endl;
+ msg << " GL_SCISSOR_BOX " << m_scissorBox[0] << m_scissorBox[1] << m_scissorBox[2]
+ << m_scissorBox[3] << endl;
+ msg << " GL_COLOR_CLEAR_VALUE "<< color << endl;
+ msg << " GL_DEPTH_CLEAR_VALUE "<< clearDepth << endl;
+ msg << " GL_BLEND "<< bool(isBlendingEnabled) << endl;
+ msg << " GL_BLEND_EQUATION_RGB" << m_map->lookUp(blendEquationRGB) << endl;
+ msg << " GL_BLEND_EQUATION_ALPHA" << m_map->lookUp(blendEquationAlpha) << endl;
+ msg << " GL_BLEND_DST_ALPHA" << m_map->lookUp(blendDestAlpha) << endl;
+ msg << " GL_BLEND_DST_RGB" << m_map->lookUp(blendDestRGB) << endl;
+ msg << " GL_BLEND_SRC_ALPHA" << m_map->lookUp(blendSrcAlpha) << endl;
+ msg << " GL_BLEND_SRC_RGB" << m_map->lookUp(blendSrcRGB) << endl;
+ msg << " GL_DEPTH_TEST "<< bool(isDepthTestEnabled) << endl;
+ msg << " GL_DEPTH_WRITEMASK "<< bool(isDepthWriteEnabled) << endl;
+ msg << " GL_POLYGON_OFFSET_FILL" << bool(polygonOffsetFillEnabled) << endl;
+ msg << " GL_POLYGON_OFFSET_FACTOR "<< polygonOffsetFactor << endl;
+ msg << " GL_POLYGON_OFFSET_UNITS "<< polygonOffsetUnits << endl;
+ msg << " GL_CULL_FACE "<< bool(isCullFaceEnabled) << endl;
+ msg << " GL_CULL_FACE_MODE "<< m_map->lookUp(cullFaceMode) << endl;
+ msg << " GL_DEPTH_FUNC "<< m_map->lookUp(depthFunc) << endl;
+ msg << " GL_FRONT_FACE "<< m_map->lookUp(frontFace) << endl;
+ msg << " GL_CURRENT_PROGRAM "<< currentProgram << endl;
+ msg << " GL_ACTIVE_TEXTURE "<< QString("0x%1").arg(activeTexture, 0, 16) << endl;
+ msg << " GL_TEXTURE_BINDING_2D "<< texBinding2D << endl;
+ msg << " GL_ELEMENT_ARRAY_BUFFER_BINDING "<< boundElementArrayBuffer << endl;
+ msg << " GL_ARRAY_BUFFER_BINDING "<< arrayBufferBinding << endl;
+ for (int i = 0; i < m_maxVertexAttribs;i++) {
+ msg << " GL_VERTEX_ATTRIB_ARRAY_ENABLED "<< i << " = "
+ << bool(vertexAttribArrayEnabledStates[i]) << endl;
+ msg << " GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING"<< i << " = "
+ << vertexAttribArrayBoundBuffers[i] << endl;
+ msg << " GL_VERTEX_ATTRIB_ARRAY_SIZE"<< i << " = "
+ << vertexAttribArraySizes[i] << endl;
+ msg << " GL_VERTEX_ATTRIB_ARRAY_TYPE"<< i << " = "
+ << vertexAttribArrayTypes[i] << endl;
+ msg << " GL_VERTEX_ATTRIB_ARRAY_NORMALIZED"<< i << " = "
+ << vertexAttribArrayNormalized[i] << endl;
+ msg << " GL_VERTEX_ATTRIB_ARRAY_STRIDE"<< i << " = "
+ << vertexAttribArrayStrides[i] << endl;
+ }
+ }
+}
+#endif
+
+void GLStateStore::restoreGLState()
+{
+#if !defined(QT_OPENGL_ES_2)
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, m_readFramebuffer);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_drawFramebuffer);
+#endif
+ glBindRenderbuffer(GL_RENDERBUFFER_BINDING, m_renderbuffer);
+
+ if (m_isScissorTestEnabled)
+ glEnable(GL_SCISSOR_TEST);
+ else
+ glDisable(GL_SCISSOR_TEST);
+
+ glScissor(m_scissorBox[0], m_scissorBox[1], m_scissorBox[2], m_scissorBox[3]);
+ glClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], m_clearColor[3]);
+ glClearDepthf(m_clearDepth);
+ if (m_isBlendingEnabled)
+ glEnable(GL_BLEND);
+ else
+ glDisable(GL_BLEND);
+
+ if (m_isDepthTestEnabled)
+ glEnable(GL_DEPTH_TEST);
+ else
+ glDisable(GL_DEPTH_TEST);
+
+ if (m_isCullFaceEnabled)
+ glEnable(GL_CULL_FACE);
+ else
+ glDisable(GL_CULL_FACE);
+
+ glCullFace(m_cullFaceMode);
+
+ glBlendEquationSeparate(m_blendEquationRGB, m_blendEquationAlpha);
+ glBlendFuncSeparate(m_blendSrcRGB, m_blendDestRGB, m_blendSrcAlpha, m_blendDestAlpha);
+
+ glDepthMask(m_isDepthWriteEnabled);
+ glDepthFunc(m_depthFunc);
+ glFrontFace(m_frontFace);
+
+ if (m_polygonOffsetFillEnabled)
+ glEnable(GL_POLYGON_OFFSET_FILL);
+ else
+ glDisable(GL_POLYGON_OFFSET_FILL);
+
+ glPolygonOffset(m_polygonOffsetFactor, m_polygonOffsetUnits);
+
+ glUseProgram(m_currentProgram);
+
+ glActiveTexture(m_activeTexture);
+ glBindTexture(GL_TEXTURE_2D, m_texBinding2D);
+
+ // Restore bound element array buffer and array buffers
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_boundElementArrayBuffer);
+ for (int i = 0; i < m_maxVertexAttribs; i++) {
+ if (m_vertexAttribArrayEnabledStates[i])
+ glEnableVertexAttribArray(i);
+ else
+ glDisableVertexAttribArray(i);
+
+ glBindBuffer(GL_ARRAY_BUFFER, m_vertexAttribArrayBoundBuffers[i]);
+ glVertexAttribPointer(i, m_vertexAttribArraySizes[i],
+ m_vertexAttribArrayTypes[i],
+ m_vertexAttribArrayNormalized[i],
+ m_vertexAttribArrayStrides[i],
+ (void *) m_vertexAttribArrayOffsets[i]);
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, m_boundArrayBuffer);
+
+#ifdef VERBOSE_STATE_STORE
+ printCurrentState(false);
+#endif
+}
+
+void GLStateStore::initGLDefaultState()
+{
+#if !defined(QT_OPENGL_ES_2)
+ m_drawFramebuffer = 0;
+ m_readFramebuffer = 0;
+#endif
+ m_renderbuffer = 0;
+ m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 1.0f;
+ m_clearDepth = 1.0f;
+ m_isBlendingEnabled = GL_FALSE;
+ m_isDepthTestEnabled = GL_FALSE;
+ m_depthFunc = GL_LESS;
+ m_isDepthWriteEnabled = GL_TRUE;
+ m_currentProgram = 0;
+ m_texBinding2D = 0;
+ for (int i = 0; i < m_maxVertexAttribs;i++) {
+ m_vertexAttribArrayEnabledStates[i] = GL_FALSE;
+ m_vertexAttribArrayBoundBuffers[i] = 0;
+ m_vertexAttribArraySizes[i] = 4;
+ m_vertexAttribArrayTypes[i] = GL_FLOAT;
+ m_vertexAttribArrayNormalized[i] = GL_FALSE;
+ m_vertexAttribArrayStrides[i] = 0;
+ m_vertexAttribArrayOffsets[i] = 0;
+ }
+ m_activeTexture = GL_TEXTURE0;
+ m_frontFace = GL_CCW;
+ m_isCullFaceEnabled = false;
+ m_cullFaceMode = GL_BACK;
+ m_blendEquationRGB = GL_FUNC_ADD;
+ m_blendEquationAlpha = GL_FUNC_ADD;
+ m_scissorBox[0] = 0;
+ m_scissorBox[1] = 0;
+ m_scissorBox[2] = 0;
+ m_scissorBox[3] = 0;
+ m_isScissorTestEnabled = GL_FALSE;
+
+ m_polygonOffsetFillEnabled = GL_FALSE;
+ m_polygonOffsetFactor = 0.0;
+ m_polygonOffsetUnits = 0.0;
+}