Repainting of only changed areas, now also for OpenGL.
svn path=/branches/work/kwin_composite/; revision=606272
This commit is contained in:
parent
0e53720687
commit
930a9248c9
4 changed files with 44 additions and 16 deletions
|
@ -31,6 +31,8 @@ glXReleaseTexImageEXT_func glXReleaseTexImageEXT;
|
|||
glXBindTexImageEXT_func glXBindTexImageEXT;
|
||||
// glActiveTexture
|
||||
glActiveTexture_func glActiveTexture;
|
||||
// glXCopySubBufferMESA
|
||||
glXCopySubBuffer_func glXCopySubBuffer;
|
||||
|
||||
|
||||
// Functions
|
||||
|
@ -52,7 +54,7 @@ void initGLX()
|
|||
glXGetProcAddress = (glXGetProcAddress_func) getProcAddress( "glxGetProcAddressARB" );
|
||||
glXBindTexImageEXT = (glXBindTexImageEXT_func) getProcAddress( "glXBindTexImageEXT" );
|
||||
glXReleaseTexImageEXT = (glXReleaseTexImageEXT_func) getProcAddress( "glXReleaseTexImageEXT" );
|
||||
|
||||
glXCopySubBuffer = (glXCopySubBuffer_func) getProcAddress( "glXCopySubBufferMESA" );
|
||||
|
||||
// Get GLX version
|
||||
int major, minor;
|
||||
|
@ -70,7 +72,6 @@ void initGL()
|
|||
if( !glActiveTexture )
|
||||
glActiveTexture = (glActiveTexture_func) getProcAddress( "glActiveTextureARB" );
|
||||
|
||||
|
||||
// Get OpenGL version
|
||||
QString glversionstring = QString((const char*)glGetString(GL_VERSION));
|
||||
QStringList glversioninfo = glversionstring.left(glversionstring.indexOf(' ')).split('.');
|
||||
|
|
|
@ -82,6 +82,9 @@ extern glXBindTexImageEXT_func glXBindTexImageEXT;
|
|||
// glActiveTexture
|
||||
typedef void (*glActiveTexture_func)(GLenum);
|
||||
extern glActiveTexture_func glActiveTexture;
|
||||
// glXCopySubBufferMESA
|
||||
typedef void (*glXCopySubBuffer_func) ( Display* , GLXDrawable, int, int, int, int );
|
||||
extern glXCopySubBuffer_func glXCopySubBuffer;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
|
|
@ -446,9 +446,39 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels )
|
|||
int mask = 0;
|
||||
paintScreen( &mask, &damage ); // call generic implementation
|
||||
glPopMatrix();
|
||||
// TODO only partial repaint for mask & PAINT_SCREEN_REGION
|
||||
flushBuffer( mask, damage );
|
||||
ungrabXServer();
|
||||
}
|
||||
|
||||
// actually paint to the screen (double-buffer swap or copy from pixmap buffer)
|
||||
void SceneOpenGL::flushBuffer( int mask, const QRegion& damage )
|
||||
{
|
||||
if( db )
|
||||
{
|
||||
if( mask & PAINT_SCREEN_REGION )
|
||||
{
|
||||
if( glXCopySubBuffer )
|
||||
{
|
||||
foreach( QRect r, damage.rects())
|
||||
glXCopySubBuffer( display(), glxbuffer, r.x(), r.y(), r.width(), r.height());
|
||||
}
|
||||
else
|
||||
{ // no idea why glScissor() is used, but Compiz has it and it doesn't seem to hurt
|
||||
glEnable( GL_SCISSOR_TEST );
|
||||
glDrawBuffer( GL_FRONT );
|
||||
foreach( QRect r, damage.rects())
|
||||
{
|
||||
// convert to OpenGL coordinates
|
||||
int y = displayHeight() - r.y() - r.height();
|
||||
glRasterPos2f( r.x(), r.y() + r.height());
|
||||
glScissor( r.x(), y, r.width(), r.height());
|
||||
glCopyPixels( r.x(), y, r.width(), r.height(), GL_COLOR );
|
||||
}
|
||||
glDrawBuffer( GL_BACK );
|
||||
glDisable( GL_SCISSOR_TEST );
|
||||
}
|
||||
}
|
||||
else
|
||||
glXSwapBuffers( display(), glxbuffer );
|
||||
glXWaitGL();
|
||||
XFlush( display());
|
||||
|
@ -457,10 +487,13 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels )
|
|||
{
|
||||
glFlush();
|
||||
glXWaitGL();
|
||||
if( mask & PAINT_SCREEN_REGION )
|
||||
foreach( QRect r, damage.rects())
|
||||
XCopyArea( display(), buffer, rootWindow(), gcroot, r.x(), r.y(), r.width(), r.height(), r.x(), r.y());
|
||||
else
|
||||
XCopyArea( display(), buffer, rootWindow(), gcroot, 0, 0, displayWidth(), displayHeight(), 0, 0 );
|
||||
XFlush( display());
|
||||
}
|
||||
ungrabXServer();
|
||||
}
|
||||
|
||||
void SceneOpenGL::paintGenericScreen( int mask, ScreenPaintData data )
|
||||
|
@ -475,15 +508,6 @@ void SceneOpenGL::paintGenericScreen( int mask, ScreenPaintData data )
|
|||
glPopMatrix();
|
||||
}
|
||||
|
||||
// the optimized case without any transformations at all
|
||||
void SceneOpenGL::paintSimpleScreen( int mask, QRegion region )
|
||||
{
|
||||
// TODO repaint only damaged areas (means also don't do glXSwapBuffers and similar)
|
||||
// For now always force redrawing of the whole area.
|
||||
region = QRegion( 0, 0, displayWidth(), displayHeight());
|
||||
Scene::paintSimpleScreen( mask, region );
|
||||
}
|
||||
|
||||
void SceneOpenGL::paintBackground( QRegion )
|
||||
{
|
||||
// TODO?
|
||||
|
|
|
@ -35,7 +35,6 @@ class SceneOpenGL
|
|||
virtual void windowDeleted( Toplevel* );
|
||||
protected:
|
||||
virtual void paintGenericScreen( int mask, ScreenPaintData data );
|
||||
virtual void paintSimpleScreen( int mask, QRegion region );
|
||||
virtual void paintBackground( QRegion region );
|
||||
private:
|
||||
void selectMode();
|
||||
|
@ -45,6 +44,7 @@ class SceneOpenGL
|
|||
void initBuffer();
|
||||
void initRenderingContext();
|
||||
bool findConfig( const int* attrs, GLXFBConfig* config, VisualID visual = None );
|
||||
void flushBuffer( int mask, const QRegion& damage );
|
||||
typedef GLuint Texture;
|
||||
GC gcroot;
|
||||
Drawable buffer;
|
||||
|
|
Loading…
Reference in a new issue