From 6641ac5648719e43621b514a0d60a8e41beb2a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Sat, 24 Jul 2010 07:32:42 +0000 Subject: [PATCH] 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 --- lib/kwinglutils.cpp | 86 +++++++++++++++++++++++++++++---------------- lib/kwinglutils.h | 18 ++++++++-- 2 files changed, 71 insertions(+), 33 deletions(-) diff --git a/lib/kwinglutils.cpp b/lib/kwinglutils.cpp index 4cd017df40..d90709179a 100644 --- a/lib/kwinglutils.cpp +++ b/lib/kwinglutils.cpp @@ -505,51 +505,27 @@ 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(), - rect.x(), rect.y() + rect.height(), - rect.x() + rect.width(), rect.y(), - rect.x() + rect.width(), rect.y() + rect.height() - }; - 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 ? 0.0f : 1.0f, - 1.0f, y_inverted ? 1.0f : 0.0f - }; - 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() + rect.x() + rect.width(), rect.y(), + rect.x() + rect.width(), rect.y() + rect.height() }; 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 + 1.0f, y_inverted ? 0.0f : 1.0f, + 1.0f, y_inverted ? 1.0f : 0.0f }; - renderGLGeometry( region, 4, verts, texcoords ); + m_vbo->setData( 4, 2, verts, texcoords ); } + m_vbo->render( region, GL_TRIANGLE_STRIP ); } void GLTexture::enableUnnormalizedTexCoords() @@ -1194,9 +1170,35 @@ class GLVertexBufferPrivate int numberVertices; int dimension; static bool supported; + QVector legacyVertices; + QVector 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; ilegacyVertices << vertices[i]; + } + d->legacyTexCoords.clear(); + d->legacyTexCoords.reserve( numberVertices * 2 ); + for( int i=0; ilegacyTexCoords << 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 ] ); diff --git a/lib/kwinglutils.h b/lib/kwinglutils.h index 3010fd0575..63897b8917 100644 --- a/lib/kwinglutils.h +++ b/lib/kwinglutils.h @@ -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& 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 * @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();