summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
authorTom Cooksey <thomas.cooksey@nokia.com>2009-12-30 08:21:34 (GMT)
committerTom Cooksey <thomas.cooksey@nokia.com>2009-12-30 12:21:35 (GMT)
commit1f1b37e613a930cc1ab871f5d11bf9742920c7f9 (patch)
tree432356825b85eba0c8a6b93cc4925dc2401b9021 /src/opengl
parent4bc5082073ef64f5e1cf120eb5190ca0f5dad268 (diff)
downloadQt-1f1b37e613a930cc1ab871f5d11bf9742920c7f9.zip
Qt-1f1b37e613a930cc1ab871f5d11bf9742920c7f9.tar.gz
Qt-1f1b37e613a930cc1ab871f5d11bf9742920c7f9.tar.bz2
Track which vertex attrib arrays are enabled in QGLContextPrivate
The GL2 engine (and probably Qt/3D) needs to track which vertex attribute arrays are currently enabled and which are disabled. As this is per-context state, the logical place to track this is in the context and not in the paint engine. This patch also makes the GL2 engine's shader manager enable/disable the appropriate attribute arrays for a given shader program when it is used. Reviewed-By: Kim
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp29
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager_p.h3
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp11
-rw-r--r--src/opengl/qgl.cpp31
-rw-r--r--src/opengl/qgl.h1
-rw-r--r--src/opengl/qgl_p.h9
6 files changed, 79 insertions, 5 deletions
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index d28d5f3..da33eb3 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -505,7 +505,27 @@ QGLShaderProgram* QGLEngineShaderManager::currentProgram()
if (currentShaderProg)
return currentShaderProg->program;
else
- return simpleProgram();
+ return sharedShaders->simpleProgram();
+}
+
+void QGLEngineShaderManager::useSimpleProgram()
+{
+ sharedShaders->simpleProgram()->bind();
+ QGLContextPrivate* ctx_d = ctx->d_func();
+ ctx_d->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true);
+ ctx_d->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false);
+ ctx_d->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false);
+ shaderProgNeedsChanging = true;
+}
+
+void QGLEngineShaderManager::useBlitProgram()
+{
+ sharedShaders->blitProgram()->bind();
+ QGLContextPrivate* ctx_d = ctx->d_func();
+ ctx_d->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true);
+ ctx_d->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, true);
+ ctx_d->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false);
+ shaderProgNeedsChanging = true;
}
QGLShaderProgram* QGLEngineShaderManager::simpleProgram()
@@ -716,6 +736,13 @@ bool QGLEngineShaderManager::useCorrectShaderProg()
customSrcStage->setUniforms(currentShaderProg->program);
}
+ // Make sure all the vertex attribute arrays the program uses are enabled (and the ones it
+ // doesn't use are disabled)
+ QGLContextPrivate* ctx_d = ctx->d_func();
+ ctx_d->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true);
+ ctx_d->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, currentShaderProg->useTextureCoords);
+ ctx_d->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, currentShaderProg->useOpacityAttribute);
+
shaderProgNeedsChanging = false;
return true;
}
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
index 1ec4cdc..a132e1b 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
@@ -468,6 +468,9 @@ public:
void setDirty(); // someone has manually changed the current shader program
bool useCorrectShaderProg(); // returns true if the shader program needed to be changed
+ void useSimpleProgram();
+ void useBlitProgram();
+
QGLShaderProgram* currentProgram(); // Returns pointer to the shader the manager has chosen
QGLShaderProgram* simpleProgram(); // Used to draw into e.g. stencil buffers
QGLShaderProgram* blitProgram(); // Used to blit a texture into the framebuffer
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index d3a9547..0574c52 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -248,9 +248,8 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray);
glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray);
- pex->shaderManager->blitProgram()->bind();
+ pex->shaderManager->useBlitProgram();
pex->shaderManager->blitProgram()->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT);
- pex->shaderManager->setDirty();
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
@@ -413,8 +412,7 @@ void QGL2PaintEngineExPrivate::setBrush(const QBrush& brush)
void QGL2PaintEngineExPrivate::useSimpleShader()
{
- shaderManager->simpleProgram()->bind();
- shaderManager->setDirty();
+ shaderManager->useSimpleProgram();
if (matrixDirty)
updateMatrix();
@@ -745,6 +743,10 @@ void QGL2PaintEngineEx::beginNativePainting()
QGLContext *ctx = d->ctx;
glUseProgram(0);
+ // Disable all the vertex attribute arrays:
+ for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i)
+ glDisableVertexAttribArray(i);
+
#ifndef QT_OPENGL_ES_2
// be nice to people who mix OpenGL 1.x code with QPainter commands
// by setting modelview and projection matrices to mirror the GL 1
@@ -1935,6 +1937,7 @@ void QGL2PaintEngineEx::ensureActive()
glViewport(0, 0, d->width, d->height);
d->needsSync = false;
d->shaderManager->setDirty();
+ d->ctx->d_func()->syncGlState();
setState(state());
}
}
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 466e851..5bb62f7 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1484,6 +1484,8 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
current_fbo = 0;
default_fbo = 0;
active_engine = 0;
+ for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i)
+ vertexAttributeArraysEnabledState[i] = false;
}
QGLContext* QGLContext::currentCtx = 0;
@@ -1874,6 +1876,35 @@ void QGLContextPrivate::cleanup()
{
}
+#define ctx q_ptr
+void QGLContextPrivate::setVertexAttribArrayEnabled(int arrayIndex, bool enabled)
+{
+ Q_ASSERT(arrayIndex < QT_GL_VERTEX_ARRAY_TRACKED_COUNT);
+ Q_ASSERT(glEnableVertexAttribArray);
+
+ if (vertexAttributeArraysEnabledState[arrayIndex] && !enabled)
+ glDisableVertexAttribArray(arrayIndex);
+
+ if (!vertexAttributeArraysEnabledState[arrayIndex] && enabled)
+ glEnableVertexAttribArray(arrayIndex);
+
+ vertexAttributeArraysEnabledState[arrayIndex] = enabled;
+}
+
+void QGLContextPrivate::syncGlState()
+{
+ Q_ASSERT(glEnableVertexAttribArray);
+ for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) {
+ if (vertexAttributeArraysEnabledState[i])
+ glEnableVertexAttribArray(i);
+ else
+ glDisableVertexAttribArray(i);
+ }
+
+}
+#undef ctx
+
+
/*!
\overload
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index 2076c46..b6cd128 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -393,6 +393,7 @@ private:
friend class QOpenGLPaintEnginePrivate;
friend class QGL2PaintEngineEx;
friend class QGL2PaintEngineExPrivate;
+ friend class QGLEngineShaderManager;
friend class QGLWindowSurface;
friend class QGLPixmapData;
friend class QGLPixmapFilterBase;
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index 99c0f33..834ff96 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -257,6 +257,10 @@ private:
class QGLTexture;
+// This probably needs to grow to GL_MAX_VERTEX_ATTRIBS, but 3 is ok for now as that's
+// all the GL2 engine uses:
+#define QT_GL_VERTEX_ARRAY_TRACKED_COUNT 3
+
class QGLContextPrivate
{
Q_DECLARE_PUBLIC(QGLContext)
@@ -276,6 +280,9 @@ public:
void cleanup();
+ void setVertexAttribArrayEnabled(int arrayIndex, bool enabled = true);
+ void syncGlState(); // Makes sure the GL context's state is what we think it is
+
#if defined(Q_WS_WIN)
HGLRC rc;
HDC dc;
@@ -332,6 +339,8 @@ public:
GLuint default_fbo;
QPaintEngine *active_engine;
+ bool vertexAttributeArraysEnabledState[QT_GL_VERTEX_ARRAY_TRACKED_COUNT];
+
static inline QGLContextGroup *contextGroup(const QGLContext *ctx) { return ctx->d_ptr->group; }
#ifdef Q_WS_WIN