- 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:
parent
ab2fa82d7c
commit
424f906ab2
5 changed files with 147 additions and 33 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue