Repainting of only changed areas, now also for OpenGL.

svn path=/branches/work/kwin_composite/; revision=606272
This commit is contained in:
Luboš Luňák 2006-11-19 20:29:41 +00:00
parent 0e53720687
commit 930a9248c9
4 changed files with 44 additions and 16 deletions

View file

@ -31,6 +31,8 @@ glXReleaseTexImageEXT_func glXReleaseTexImageEXT;
glXBindTexImageEXT_func glXBindTexImageEXT; glXBindTexImageEXT_func glXBindTexImageEXT;
// glActiveTexture // glActiveTexture
glActiveTexture_func glActiveTexture; glActiveTexture_func glActiveTexture;
// glXCopySubBufferMESA
glXCopySubBuffer_func glXCopySubBuffer;
// Functions // Functions
@ -52,7 +54,7 @@ void initGLX()
glXGetProcAddress = (glXGetProcAddress_func) getProcAddress( "glxGetProcAddressARB" ); glXGetProcAddress = (glXGetProcAddress_func) getProcAddress( "glxGetProcAddressARB" );
glXBindTexImageEXT = (glXBindTexImageEXT_func) getProcAddress( "glXBindTexImageEXT" ); glXBindTexImageEXT = (glXBindTexImageEXT_func) getProcAddress( "glXBindTexImageEXT" );
glXReleaseTexImageEXT = (glXReleaseTexImageEXT_func) getProcAddress( "glXReleaseTexImageEXT" ); glXReleaseTexImageEXT = (glXReleaseTexImageEXT_func) getProcAddress( "glXReleaseTexImageEXT" );
glXCopySubBuffer = (glXCopySubBuffer_func) getProcAddress( "glXCopySubBufferMESA" );
// Get GLX version // Get GLX version
int major, minor; int major, minor;
@ -70,7 +72,6 @@ void initGL()
if( !glActiveTexture ) if( !glActiveTexture )
glActiveTexture = (glActiveTexture_func) getProcAddress( "glActiveTextureARB" ); glActiveTexture = (glActiveTexture_func) getProcAddress( "glActiveTextureARB" );
// Get OpenGL version // Get OpenGL version
QString glversionstring = QString((const char*)glGetString(GL_VERSION)); QString glversionstring = QString((const char*)glGetString(GL_VERSION));
QStringList glversioninfo = glversionstring.left(glversionstring.indexOf(' ')).split('.'); QStringList glversioninfo = glversionstring.left(glversionstring.indexOf(' ')).split('.');

View file

@ -82,6 +82,9 @@ extern glXBindTexImageEXT_func glXBindTexImageEXT;
// glActiveTexture // glActiveTexture
typedef void (*glActiveTexture_func)(GLenum); typedef void (*glActiveTexture_func)(GLenum);
extern glActiveTexture_func glActiveTexture; extern glActiveTexture_func glActiveTexture;
// glXCopySubBufferMESA
typedef void (*glXCopySubBuffer_func) ( Display* , GLXDrawable, int, int, int, int );
extern glXCopySubBuffer_func glXCopySubBuffer;
} // namespace } // namespace

View file

@ -446,9 +446,39 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels )
int mask = 0; int mask = 0;
paintScreen( &mask, &damage ); // call generic implementation paintScreen( &mask, &damage ); // call generic implementation
glPopMatrix(); 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( 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 ); glXSwapBuffers( display(), glxbuffer );
glXWaitGL(); glXWaitGL();
XFlush( display()); XFlush( display());
@ -457,10 +487,13 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels )
{ {
glFlush(); glFlush();
glXWaitGL(); 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 ); XCopyArea( display(), buffer, rootWindow(), gcroot, 0, 0, displayWidth(), displayHeight(), 0, 0 );
XFlush( display()); XFlush( display());
} }
ungrabXServer();
} }
void SceneOpenGL::paintGenericScreen( int mask, ScreenPaintData data ) void SceneOpenGL::paintGenericScreen( int mask, ScreenPaintData data )
@ -475,15 +508,6 @@ void SceneOpenGL::paintGenericScreen( int mask, ScreenPaintData data )
glPopMatrix(); 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 ) void SceneOpenGL::paintBackground( QRegion )
{ {
// TODO? // TODO?

View file

@ -35,7 +35,6 @@ class SceneOpenGL
virtual void windowDeleted( Toplevel* ); virtual void windowDeleted( Toplevel* );
protected: protected:
virtual void paintGenericScreen( int mask, ScreenPaintData data ); virtual void paintGenericScreen( int mask, ScreenPaintData data );
virtual void paintSimpleScreen( int mask, QRegion region );
virtual void paintBackground( QRegion region ); virtual void paintBackground( QRegion region );
private: private:
void selectMode(); void selectMode();
@ -45,6 +44,7 @@ class SceneOpenGL
void initBuffer(); void initBuffer();
void initRenderingContext(); void initRenderingContext();
bool findConfig( const int* attrs, GLXFBConfig* config, VisualID visual = None ); bool findConfig( const int* attrs, GLXFBConfig* config, VisualID visual = None );
void flushBuffer( int mask, const QRegion& damage );
typedef GLuint Texture; typedef GLuint Texture;
GC gcroot; GC gcroot;
Drawable buffer; Drawable buffer;