- Add optional color argument to renderGLGeometry() functions. If specified, it's used as vertex colors

array when rendering.
- Rearrange some renderGLGeometry() parameters.
- Don't use opengl arrays and glDrawArrays() when rendering a small number of vertices since in this
  case overhead of enabling/disabling the array is too big. Use immediate mode instead in such case.

svn path=/trunk/KDE/kdebase/workspace/; revision=675467
This commit is contained in:
Rivo Laks 2007-06-14 10:05:51 +00:00
parent ab2fa82d7c
commit 424f906ab2
5 changed files with 147 additions and 33 deletions

View file

@ -436,7 +436,7 @@ void BoxSwitchEffect::paintFrame()
frame_area.x() + frame_area.width(), frame_area.y() + frame_area.height(),
frame_area.x() + frame_area.width(), frame_area.y()
};
renderGLGeometry( verts, NULL, 4 );
renderGLGeometry( 4, verts );
glPopAttrib();
}
#endif
@ -479,7 +479,7 @@ void BoxSwitchEffect::paintHighlight( QRect area, QString text )
area.x() + area.width(), area.y() + area.height(),
area.x() + area.width(), area.y()
};
renderGLGeometry( verts, NULL, 4 );
renderGLGeometry( 4, verts );
glPopAttrib();
}
#endif
@ -597,7 +597,7 @@ void BoxSwitchEffect::paintWindowIcon( EffectWindow* w )
1, 0,
1, 1
};
renderGLGeometry( verts, texcoords, 4 );
renderGLGeometry( 4, verts, texcoords );
windows[ w ]->iconTexture.unbind();
glPopAttrib();
}

View file

@ -75,7 +75,7 @@ void ShadowEffect::drawShadow( EffectWindow* w, int mask, QRegion region, Window
w->width(), w->height(),
w->width(), 0
};
renderGLGeometry( mask, region, verts, NULL, 4 );
renderGLGeometry( mask, region, 4, verts );
glPopMatrix();
glPopAttrib();

View file

@ -110,52 +110,146 @@ int nearestPowerOfTwo( int x )
return 1 << last;
}
void renderGLGeometry( const float* vertices, const float* texture, int count, int dim, int stride )
void renderGLGeometry( int count, const float* vertices, const float* texture, const float* color,
int dim, int stride )
{
return renderGLGeometry( false, QRegion(), vertices, texture, count, dim, stride );
return renderGLGeometry( false, QRegion(), count, vertices, texture, color, dim, stride );
}
void renderGLGeometry( int mask, QRegion region, const float* vertices, const float* texture, int count,
void renderGLGeometry( int mask, const QRegion& region, int count,
const float* vertices, const float* texture, const float* color,
int dim, int stride )
{
return renderGLGeometry( !( mask & ( Effect::PAINT_WINDOW_TRANSFORMED | Effect::PAINT_SCREEN_TRANSFORMED )),
region, vertices, texture, count, dim, stride );
region, count, vertices, texture, color, dim, stride );
}
void renderGLGeometry( bool clip, QRegion region, const float* vertices, const float* texture, int count,
void renderGLGeometry( bool clip, const QRegion& region, int count,
const float* vertices, const float* texture, const float* color,
int dim, int stride )
{
glPushAttrib( GL_ENABLE_BIT );
glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
// Enable arrays
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( dim, GL_FLOAT, stride, vertices );
if( texture != NULL )
// Using arrays only makes sense if we have larger number of vertices.
// Otherwise overhead of enabling/disabling them is too big.
bool use_arrays = (count > 5);
if( use_arrays )
{
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glTexCoordPointer( 2, GL_FLOAT, stride, texture );
glPushAttrib( GL_ENABLE_BIT );
glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
// Enable arrays
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( dim, GL_FLOAT, stride, vertices );
if( texture != NULL )
{
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glTexCoordPointer( 2, GL_FLOAT, stride, texture );
}
if( color != NULL )
{
glEnableClientState( GL_COLOR_ARRAY );
glTexCoordPointer( 4, GL_FLOAT, stride, color );
}
}
// Render
if( !clip )
{
// Just draw the entire window, no clipping
glDrawArrays( GL_QUADS, 0, count );
if( use_arrays )
glDrawArrays( GL_QUADS, 0, count );
else
renderGLGeometryImmediate( count, vertices, texture, color, dim, stride );
}
else
{
// Make sure there's only a single quad (no transformed vertices)
// Clip using scissoring
glEnable( GL_SCISSOR_TEST );
int dh = displayHeight();
foreach( QRect r, region.rects())
if( use_arrays )
{
// Scissor rect has to be given in OpenGL coords
glScissor(r.x(), dh - r.y() - r.height(), r.width(), r.height());
glDrawArrays( GL_QUADS, 0, count );
foreach( QRect r, region.rects())
{
// Scissor rect has to be given in OpenGL coords
glScissor(r.x(), dh - r.y() - r.height(), r.width(), r.height());
glDrawArrays( GL_QUADS, 0, count );
}
}
else
{
foreach( QRect r, region.rects())
{
// Scissor rect has to be given in OpenGL coords
glScissor(r.x(), dh - r.y() - r.height(), r.width(), r.height());
renderGLGeometryImmediate( count, vertices, texture, color, dim, stride );
}
}
}
glPopClientAttrib();
glPopAttrib();
if( use_arrays )
{
glPopClientAttrib();
glPopAttrib();
}
}
void renderGLGeometryImmediate( int count, const float* vertices, const float* texture, const float* color,
int dim, int stride )
{
// Find out correct glVertex*fv function according to dim parameter.
void ( *glVertexFunc )( const float* ) = glVertex2fv;
if( dim == 3 )
glVertexFunc = glVertex3fv;
else if( dim == 4 )
glVertexFunc = glVertex4fv;
// These are number of _floats_ per item, not _bytes_ per item as opengl uses.
int vsize, tsize, csize;
vsize = tsize = csize = stride / sizeof(float);
if( !stride )
{
// 0 means that arrays are tightly packed. This gives us different
// strides for different arrays
vsize = dim;
tsize = 2;
csize = 4;
}
glBegin( GL_QUADS );
// This sucks. But makes it faster.
if( texture && color )
{
for( int i = 0; i < count; i++ )
{
glTexCoord2fv( texture + i*tsize );
glColor4fv( color + i*csize );
glVertexFunc( vertices + i*vsize );
}
}
else if( texture )
{
for( int i = 0; i < count; i++ )
{
glTexCoord2fv( texture + i*tsize );
glVertexFunc( vertices + i*vsize );
}
}
else if( color )
{
for( int i = 0; i < count; i++ )
{
glColor4fv( color + i*csize );
glVertexFunc( vertices + i*vsize );
}
}
else
{
for( int i = 0; i < count; i++ )
glVertexFunc( vertices + i*vsize );
}
glEnd();
}
//****************************************
// GLTexture
//****************************************
@ -331,7 +425,7 @@ void GLTexture::render( bool clip, QRegion region, const QRect& rect )
1, 0,
1, 1
};
renderGLGeometry( clip, region, verts, texcoords, 4 );
renderGLGeometry( clip, region, 4, verts, texcoords );
}
void GLTexture::enableUnnormalizedTexCoords()

View file

@ -57,14 +57,34 @@ inline bool KWIN_EXPORT isPowerOfTwo( int x ) { return (( x & ( x - 1 )) == 0 );
**/
int KWIN_EXPORT nearestPowerOfTwo( int x );
// renders quads using the given vertices
KWIN_EXPORT void renderGLGeometry( bool clip, QRegion region, const float* vertices, const float* texture, int count,
/**
* Renders quads using given vertices.
* If texture is not 0, each texture coordinate much have two components (st).
* If color is not 0, each color much have four components (rgba).
*
* @param count number of vertices to use.
* @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)!
**/
KWIN_EXPORT void renderGLGeometry( bool clip, const QRegion& region, int count,
const float* vertices, const float* texture = 0, const float* color = 0,
int dim = 2, int stride = 0 );
// sets clip according to mask
KWIN_EXPORT void renderGLGeometry( int mask, QRegion region, const float* vertices, const float* texture, int count,
/**
* Same as above, sets clip parameter according to mask.
**/
KWIN_EXPORT void renderGLGeometry( int mask, const QRegion& region, int count,
const float* vertices, const float* texture = 0, const float* color = 0,
int dim = 2, int stride = 0 );
// clip = false
KWIN_EXPORT void renderGLGeometry( const float* vertices, const float* texture, int count,
/**
* Same as above, renders without clipping
**/
KWIN_EXPORT void renderGLGeometry( int count,
const float* vertices, const float* texture = 0, const float* color = 0,
int dim = 2, int stride = 0 );
KWIN_EXPORT void renderGLGeometryImmediate( int count,
const float* vertices, const float* texture = 0, const float* color = 0,
int dim = 2, int stride = 0 );
class KWIN_EXPORT GLTexture

View file

@ -1256,8 +1256,8 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat
// Render geometry
region.translate( toplevel->x(), toplevel->y() ); // Back to screen coords
renderGLGeometry( mask, region, verticeslist[ 0 ].pos, verticeslist[ 0 ].texcoord,
verticeslist.count(), 3, sizeof( Vertex ));
renderGLGeometry( mask, region, verticeslist.count(),
verticeslist[ 0 ].pos, verticeslist[ 0 ].texcoord, 0, 3, sizeof( Vertex ));
texture.disableUnnormalizedTexCoords();
glPopMatrix();