kwin: Do some more refactoring in GLVertexBuffer

Consolidate the code for binding and unbinding the vertex arrays into
two new methods called bindArrays() and unbindArrays() respectively.

This patch also removes the three paint implementations, since the only
difference between them is the code that sets up the arrays. The actual
painting code is moved into GLVertexBuffer::render(), which uses the
new methods to bind and unbind the arrays.
This commit is contained in:
Fredrik Höglund 2012-09-26 22:34:12 +02:00
parent 3f69bb0e7f
commit c41d05d36c

View file

@ -1237,6 +1237,8 @@ public:
}
void interleaveArrays(float *array, int dim, const float *vertices, const float *texcoords, int count);
void bindArrays();
void unbindArrays();
GLvoid *mapNextFreeRange(size_t size);
GLuint buffer;
@ -1255,13 +1257,6 @@ public:
intptr_t nextOffset;
intptr_t vertexAddress;
intptr_t texCoordAddress;
//! VBO is not supported
void legacyPainting(QRegion region, GLenum primitiveMode, bool hardwareClipping);
//! VBO and shaders are both supported
void corePainting(const QRegion& region, GLenum primitiveMode, bool hardwareClipping);
//! VBO is supported, but shaders are not supported
void fallbackPainting(const QRegion& region, GLenum primitiveMode, bool hardwareClipping);
};
bool GLVertexBufferPrivate::supported = false;
@ -1309,44 +1304,11 @@ void GLVertexBufferPrivate::interleaveArrays(float *dst, int dim,
}
}
void GLVertexBufferPrivate::legacyPainting(QRegion region, GLenum primitiveMode, bool hardwareClipping)
void GLVertexBufferPrivate::bindArrays()
{
#ifndef KWIN_HAVE_OPENGL_1
Q_UNUSED(region)
Q_UNUSED(primitiveMode)
Q_UNUSED(hardwareClipping)
#else
// Enable arrays
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(dimension, GL_FLOAT, stride, (const GLvoid *) vertexAddress);
if (useTexCoords) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, stride, (const GLvoid *) texCoordAddress);
}
if (useColor) {
glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF());
}
if (!hardwareClipping) {
glDrawArrays(primitiveMode, 0, vertexCount);
} else {
foreach (const QRect& r, region.rects()) {
glScissor(r.x(), displayHeight() - r.y() - r.height(), r.width(), r.height());
glDrawArrays(primitiveMode, 0, vertexCount);
}
}
glDisableClientState(GL_VERTEX_ARRAY);
if (useTexCoords) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
#ifndef KWIN_HAVE_OPENGLES
if (ShaderManager::instance()->isShaderBound()) {
#endif
}
void GLVertexBufferPrivate::corePainting(const QRegion& region, GLenum primitiveMode, bool hardwareClipping)
{
GLShader *shader = ShaderManager::instance()->getBoundShader();
if (useColor) {
@ -1364,55 +1326,47 @@ void GLVertexBufferPrivate::corePainting(const QRegion& region, GLenum primitive
glEnableVertexAttribArray(VA_TexCoord);
}
if (!hardwareClipping) {
glDrawArrays(primitiveMode, 0, vertexCount);
glBindBuffer(GL_ARRAY_BUFFER, 0);
#ifndef KWIN_HAVE_OPENGLES
} else {
foreach (const QRect& r, region.rects()) {
glScissor(r.x(), displayHeight() - r.y() - r.height(), r.width(), r.height());
glDrawArrays(primitiveMode, 0, vertexCount);
}
if (GLVertexBufferPrivate::supported)
glBindBuffer(GL_ARRAY_BUFFER, buffer);
// FIXME Is there any good reason to not leave this array permanently enabled?
// When do we not use it in the GL 1.x path?
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(dimension, GL_FLOAT, stride, (const GLvoid *) vertexAddress);
if (useTexCoords) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, stride, (const GLvoid *) texCoordAddress);
}
if (useColor)
glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF());
if (GLVertexBufferPrivate::supported)
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
#endif
}
void GLVertexBufferPrivate::unbindArrays()
{
#ifndef KWIN_HAVE_OPENGLES
if (ShaderManager::instance()->isShaderBound()) {
#endif
glDisableVertexAttribArray(VA_Position);
if (useTexCoords) {
glDisableVertexAttribArray(VA_TexCoord);
}
glDisableVertexAttribArray(VA_Position);
}
void GLVertexBufferPrivate::fallbackPainting(const QRegion& region, GLenum primitiveMode, bool hardwareClipping)
{
#ifndef KWIN_HAVE_OPENGL_1
Q_UNUSED(region)
Q_UNUSED(primitiveMode)
Q_UNUSED(hardwareClipping)
#else
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glVertexPointer(dimension, GL_FLOAT, stride, (const GLvoid *) vertexAddress);
glTexCoordPointer(2, GL_FLOAT, stride, (const GLvoid *) texCoordAddress);
if (useColor) {
glColor4f(color.redF(), color.greenF(), color.blueF(), color.alphaF());
}
// Clip using scissoring
if (!hardwareClipping) {
glDrawArrays(primitiveMode, 0, vertexCount);
#ifndef KWIN_HAVE_OPENGLES
} else {
foreach (const QRect& r, region.rects()) {
glScissor(r.x(), displayHeight() - r.y() - r.height(), r.width(), r.height());
glDrawArrays(primitiveMode, 0, vertexCount);
}
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Assume that the conventional arrays were enabled
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
#endif
}
@ -1521,13 +1475,19 @@ void GLVertexBuffer::render(GLenum primitiveMode)
void GLVertexBuffer::render(const QRegion& region, GLenum primitiveMode, bool hardwareClipping)
{
if (!GLVertexBufferPrivate::supported) {
d->legacyPainting(region, primitiveMode, hardwareClipping);
} else if (ShaderManager::instance()->isShaderBound()) {
d->corePainting(region, primitiveMode, hardwareClipping);
d->bindArrays();
if (!hardwareClipping) {
glDrawArrays(primitiveMode, 0, d->vertexCount);
} else {
d->fallbackPainting(region, primitiveMode, hardwareClipping);
// Clip using scissoring
foreach (const QRect &r, region.rects()) {
glScissor(r.x(), displayHeight() - r.y() - r.height(), r.width(), r.height());
glDrawArrays(primitiveMode, 0, d->vertexCount);
}
}
d->unbindArrays();
}
bool GLVertexBuffer::isSupported()