GLRenderBuffer supports legacy painting if VBOs are not available.

This gives us one API for both legacy and modern painting.
All glRenderGeometry* calls are deprecated as they use quads and
legacy painting.

svn path=/trunk/KDE/kdebase/workspace/; revision=1153911
This commit is contained in:
Martin Gräßlin 2010-07-24 07:32:42 +00:00
parent 8ddf5106eb
commit 6641ac5648
2 changed files with 71 additions and 33 deletions

View file

@ -505,12 +505,10 @@ void GLTexture::render( QRegion region, const QRect& rect )
if( rect != m_cachedGeometry )
{
m_cachedGeometry = rect;
if( !m_vbo && GLVertexBuffer::isSupported() )
if( !m_vbo )
{
m_vbo = new GLVertexBuffer( KWin::GLVertexBuffer::Static );
}
if( m_vbo )
{
const float verts[ 4 * 2 ] =
{
rect.x(), rect.y(),
@ -527,30 +525,8 @@ void GLTexture::render( QRegion region, const QRect& rect )
};
m_vbo->setData( 4, 2, verts, texcoords );
}
}
if( m_vbo )
{
m_vbo->render( region, GL_TRIANGLE_STRIP );
}
else
{
const float verts[ 4 * 2 ] =
{
rect.x(), rect.y(),
rect.x(), rect.y() + rect.height(),
rect.x() + rect.width(), rect.y() + rect.height(),
rect.x() + rect.width(), rect.y()
};
const float texcoords[ 4 * 2 ] =
{
0.0f, y_inverted ? 0.0f : 1.0f, // y needs to be swapped (normalized coords)
0.0f, y_inverted ? 1.0f : 0.0f,
1.0f, y_inverted ? 1.0f : 0.0f,
1.0f, y_inverted ? 0.0f : 1.0f
};
renderGLGeometry( region, 4, verts, texcoords );
}
}
void GLTexture::enableUnnormalizedTexCoords()
{
@ -1194,9 +1170,35 @@ class GLVertexBufferPrivate
int numberVertices;
int dimension;
static bool supported;
QVector<float> legacyVertices;
QVector<float> legacyTexCoords;
void legacyPainting( QRegion region, GLenum primitiveMode );
};
bool GLVertexBufferPrivate::supported = false;
void GLVertexBufferPrivate::legacyPainting( QRegion region, GLenum primitiveMode )
{
kDebug(1212) << "Legacy Painting";
// Enable arrays
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( dimension, GL_FLOAT, 0, legacyVertices.constData() );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glTexCoordPointer( 2, GL_FLOAT, 0, legacyTexCoords.constData() );
// Clip using scissoring
PaintClipper pc( region );
for( PaintClipper::Iterator iterator;
!iterator.isDone();
iterator.next())
{
glDrawArrays( primitiveMode, 0, numberVertices );
}
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
}
//*********************************
// GLVertexBuffer
//*********************************
@ -1214,6 +1216,23 @@ void GLVertexBuffer::setData( int numberVertices, int dim, const float* vertices
{
d->numberVertices = numberVertices;
d->dimension = dim;
if( !GLVertexBufferPrivate::supported )
{
// legacy data
d->legacyVertices.clear();
d->legacyVertices.reserve( numberVertices * dim );
for( int i=0; i<numberVertices*dim; ++i)
{
d->legacyVertices << vertices[i];
}
d->legacyTexCoords.clear();
d->legacyTexCoords.reserve( numberVertices * 2 );
for( int i=0; i<numberVertices*2; ++i)
{
d->legacyTexCoords << texcoords[i];
}
return;
}
GLenum hint;
switch( d->hint )
{
@ -1252,6 +1271,11 @@ void GLVertexBuffer::render( GLenum primitiveMode )
void GLVertexBuffer::render( const QRegion& region, GLenum primitiveMode )
{
if( !GLVertexBufferPrivate::supported )
{
d->legacyPainting( region, primitiveMode );
return;
}
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glBindBuffer( GL_ARRAY_BUFFER, d->buffers[ 0 ] );

View file

@ -86,23 +86,32 @@ int KWIN_EXPORT nearestPowerOfTwo( int x );
* @param dim number of components per vertex coordinate in vertices array.
* @param stride byte offset of consecutive elements in arrays. If 0, then
* arrays must be tighly packed. Stride must be a multiple of sizeof(float)!
* @deprecated Use GLVertexBuffer
* @see GLVertexBuffer
**/
KWIN_EXPORT void renderGLGeometry( const QRegion& region, int count,
const float* vertices, const float* texture = 0, const float* color = 0,
int dim = 2, int stride = 0 );
/**
* Same as above, renders without specified region
* @deprecated Use GLVertexBuffer
* @see GLVertexBuffer
**/
KWIN_EXPORT void renderGLGeometry( int count,
const float* vertices, const float* texture = 0, const float* color = 0,
int dim = 2, int stride = 0 );
/**
* @deprecated Use GLVertexBuffer
* @see GLVertexBuffer
**/
KWIN_EXPORT void renderGLGeometryImmediate( int count,
const float* vertices, const float* texture = 0, const float* color = 0,
int dim = 2, int stride = 0 );
/**
* @deprecated Quads are not available in OpenGL ES
**/
KWIN_EXPORT void addQuadVertices( QVector<float>& verts, float x1, float y1, float x2, float y2 );
@ -305,6 +314,9 @@ class KWIN_EXPORT GLRenderTarget
* vertex data and to store them on graphics memory. It is the only allowed way to pass vertex
* data to the GPU in OpenGL ES 2 and OpenGL 3 with forward compatible mode.
*
* If VBOs are not supported on the used OpenGL profile this class falls back to legacy
* rendering using client arrays. Therefore this class should always be used for rendering geometries.
*
* @author Martin Gräßlin <kde@martin-graesslin.com>
* @since 4.6
*/
@ -350,6 +362,8 @@ class KWIN_EXPORT GLVertexBuffer
*/
static void initStatic();
/**
* Returns true if VBOs are supported, it is save to use this class even if VBOs are not
* supported.
* @returns true if vertex buffer objects are supported
*/
static bool isSupported();