Separate more generic and simple screen paint.
svn path=/branches/work/kwin_composite/; revision=595559
This commit is contained in:
parent
1069654076
commit
17e46e32fb
2 changed files with 71 additions and 38 deletions
100
scene_opengl.cpp
100
scene_opengl.cpp
|
@ -32,6 +32,7 @@ GLXFBConfig SceneOpenGL::fbcdrawable;
|
||||||
GLXContext SceneOpenGL::context;
|
GLXContext SceneOpenGL::context;
|
||||||
GLXPixmap SceneOpenGL::glxroot;
|
GLXPixmap SceneOpenGL::glxroot;
|
||||||
bool SceneOpenGL::tfp_mode; // using glXBindTexImageEXT (texture_from_pixmap)
|
bool SceneOpenGL::tfp_mode; // using glXBindTexImageEXT (texture_from_pixmap)
|
||||||
|
bool SceneOpenGL::root_db; // destination drawable is double-buffered
|
||||||
|
|
||||||
typedef void (*glXBindTexImageEXT_func)( Display* dpy, GLXDrawable drawable,
|
typedef void (*glXBindTexImageEXT_func)( Display* dpy, GLXDrawable drawable,
|
||||||
int buffer, const int* attrib_list );
|
int buffer, const int* attrib_list );
|
||||||
|
@ -180,6 +181,7 @@ void SceneOpenGL::initBuffer()
|
||||||
{
|
{
|
||||||
buffer = rootWindow();
|
buffer = rootWindow();
|
||||||
glxroot = glXCreateWindow( display(), fbcroot, buffer, NULL );
|
glxroot = glXCreateWindow( display(), fbcroot, buffer, NULL );
|
||||||
|
glDrawBuffer( GL_BACK );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -262,15 +264,33 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList windows )
|
||||||
{
|
{
|
||||||
grabXServer();
|
grabXServer();
|
||||||
glXWaitX();
|
glXWaitX();
|
||||||
|
if( /*generic case*/false )
|
||||||
|
paintGenericScreen( windows );
|
||||||
|
else
|
||||||
|
paintSimpleScreen( damage, windows );
|
||||||
|
ungrabXServer();
|
||||||
|
checkGLError( "PostPaint" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// the generic painting code that should eventually handle even
|
||||||
|
// transformations
|
||||||
|
void SceneOpenGL::paintGenericScreen( ToplevelList windows )
|
||||||
|
{
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glClearColor( 0, 0, 0, 1 );
|
glClearColor( 0, 0, 0, 1 );
|
||||||
glClear( GL_COLOR_BUFFER_BIT );
|
glClear( GL_COLOR_BUFFER_BIT );
|
||||||
glScalef( 1, -1, 1 );
|
glScalef( 1, -1, 1 );
|
||||||
glTranslatef( 0, -displayHeight(), 0 );
|
glTranslatef( 0, -displayHeight(), 0 );
|
||||||
if( /*generic case*/false )
|
paintBackground( infiniteRegion());
|
||||||
paintGenericScreen( windows );
|
foreach( Toplevel* c, windows ) // bottom to top
|
||||||
else
|
{
|
||||||
paintSimpleScreen( damage, windows );
|
assert( this->windows.contains( c ));
|
||||||
|
Window& w = this->windows[ c ];
|
||||||
|
if( !w.isVisible())
|
||||||
|
continue;
|
||||||
|
w.bindTexture();
|
||||||
|
w.paint( infiniteRegion(), PAINT_OPAQUE | PAINT_TRANSLUCENT );
|
||||||
|
}
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
if( root_db )
|
if( root_db )
|
||||||
glXSwapBuffers( display(), glxroot );
|
glXSwapBuffers( display(), glxroot );
|
||||||
|
@ -281,34 +301,16 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList windows )
|
||||||
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();
|
|
||||||
checkGLError( "PostPaint" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// the generic painting code that should eventually handle even
|
|
||||||
// transformations
|
|
||||||
void SceneOpenGL::paintGenericScreen( ToplevelList windows )
|
|
||||||
{
|
|
||||||
foreach( Toplevel* c, windows ) // bottom to top
|
|
||||||
{
|
|
||||||
assert( this->windows.contains( c ));
|
|
||||||
Window& w = this->windows[ c ];
|
|
||||||
if( !w.isVisible())
|
|
||||||
continue;
|
|
||||||
w.bindTexture();
|
|
||||||
if( !w.isOpaque())
|
|
||||||
{
|
|
||||||
glEnable( GL_BLEND );
|
|
||||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
|
||||||
}
|
|
||||||
w.paint( infiniteRegion());
|
|
||||||
glDisable( GL_BLEND );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the optimized case without any transformations at all
|
// the optimized case without any transformations at all
|
||||||
void SceneOpenGL::paintSimpleScreen( QRegion damage, ToplevelList windows )
|
void SceneOpenGL::paintSimpleScreen( QRegion damage, ToplevelList windows )
|
||||||
{
|
{
|
||||||
|
glPushMatrix();
|
||||||
|
glClearColor( 0, 0, 0, 1 );
|
||||||
|
glClear( GL_COLOR_BUFFER_BIT );
|
||||||
|
glScalef( 1, -1, 1 );
|
||||||
|
glTranslatef( 0, -displayHeight(), 0 );
|
||||||
QList< Phase2Data > phase2;
|
QList< Phase2Data > phase2;
|
||||||
QRegion region = damage;
|
QRegion region = damage;
|
||||||
// TODO repaint only damaged areas (means also don't do glXSwapBuffers and similar)
|
// TODO repaint only damaged areas (means also don't do glXSwapBuffers and similar)
|
||||||
|
@ -330,7 +332,7 @@ void SceneOpenGL::paintSimpleScreen( QRegion damage, ToplevelList windows )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
w.bindTexture();
|
w.bindTexture();
|
||||||
w.paint( region );
|
w.paint( region, PAINT_OPAQUE );
|
||||||
// window is opaque, clip windows below
|
// window is opaque, clip windows below
|
||||||
region -= w.shape().translated( w.x(), w.y());
|
region -= w.shape().translated( w.x(), w.y());
|
||||||
}
|
}
|
||||||
|
@ -339,10 +341,17 @@ void SceneOpenGL::paintSimpleScreen( QRegion damage, ToplevelList windows )
|
||||||
{
|
{
|
||||||
Window& w = *d.window;
|
Window& w = *d.window;
|
||||||
w.bindTexture();
|
w.bindTexture();
|
||||||
glEnable( GL_BLEND );
|
w.paint( d.region, PAINT_TRANSLUCENT );
|
||||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
}
|
||||||
w.paint( d.region );
|
glPopMatrix();
|
||||||
glDisable( GL_BLEND );
|
if( root_db )
|
||||||
|
glXSwapBuffers( display(), glxroot );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glFlush();
|
||||||
|
glXWaitGL();
|
||||||
|
XCopyArea( display(), buffer, rootWindow(), gcroot, 0, 0, displayWidth(), displayHeight(), 0, 0 );
|
||||||
|
XFlush( display());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,6 +524,8 @@ void SceneOpenGL::Window::bindTexture()
|
||||||
// the pixmap
|
// the pixmap
|
||||||
glXDestroyPixmap( display(), pixmap );
|
glXDestroyPixmap( display(), pixmap );
|
||||||
XFreePixmap( display(), pix );
|
XFreePixmap( display(), pix );
|
||||||
|
if( root_db )
|
||||||
|
glDrawBuffer( GL_BACK );
|
||||||
}
|
}
|
||||||
#ifdef ALPHA_CLEAR_COPY
|
#ifdef ALPHA_CLEAR_COPY
|
||||||
if( alpha_clear )
|
if( alpha_clear )
|
||||||
|
@ -587,7 +598,7 @@ static void quadPaint( int x1, int y1, int x2, int y2, bool invert_y )
|
||||||
glVertex2i( x1, y2 );
|
glVertex2i( x1, y2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneOpenGL::Window::paint( QRegion region )
|
void SceneOpenGL::Window::paint( QRegion region, int mask )
|
||||||
{
|
{
|
||||||
// paint only requested areas
|
// paint only requested areas
|
||||||
if( region != infiniteRegion()) // avoid integer overflow
|
if( region != infiniteRegion()) // avoid integer overflow
|
||||||
|
@ -595,15 +606,31 @@ void SceneOpenGL::Window::paint( QRegion region )
|
||||||
region &= shape();
|
region &= shape();
|
||||||
if( region.isEmpty())
|
if( region.isEmpty())
|
||||||
return;
|
return;
|
||||||
// TODO for double-buffered root glDrawBuffer( GL_BACK );
|
|
||||||
glXMakeContextCurrent( display(), glxroot, glxroot, context );
|
glXMakeContextCurrent( display(), glxroot, glxroot, context );
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef( x(), y(), 0 );
|
glTranslatef( x(), y(), 0 );
|
||||||
|
if( mask & ( PAINT_OPAQUE | PAINT_TRANSLUCENT ))
|
||||||
|
{}
|
||||||
|
else if( mask & PAINT_OPAQUE )
|
||||||
|
{
|
||||||
|
if( !isOpaque())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if( mask & PAINT_TRANSLUCENT )
|
||||||
|
{
|
||||||
|
if( isOpaque())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool was_blend = glIsEnabled( GL_BLEND );
|
||||||
|
if( !isOpaque())
|
||||||
|
{
|
||||||
|
glEnable( GL_BLEND );
|
||||||
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||||
|
}
|
||||||
if( toplevel->opacity() != 1.0 )
|
if( toplevel->opacity() != 1.0 )
|
||||||
{
|
{
|
||||||
if( toplevel->hasAlpha())
|
if( toplevel->hasAlpha())
|
||||||
{
|
{
|
||||||
glEnable( GL_BLEND );
|
|
||||||
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||||
glColor4f( toplevel->opacity(), toplevel->opacity(), toplevel->opacity(),
|
glColor4f( toplevel->opacity(), toplevel->opacity(), toplevel->opacity(),
|
||||||
toplevel->opacity());
|
toplevel->opacity());
|
||||||
|
@ -632,8 +659,9 @@ void SceneOpenGL::Window::paint( QRegion region )
|
||||||
{
|
{
|
||||||
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
|
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
|
||||||
glColor4f( 0, 0, 0, 0 );
|
glColor4f( 0, 0, 0, 0 );
|
||||||
glDisable( GL_BLEND );
|
|
||||||
}
|
}
|
||||||
|
if( !was_blend )
|
||||||
|
glDisable( GL_BLEND );
|
||||||
glDisable( GL_TEXTURE_RECTANGLE_ARB );
|
glDisable( GL_TEXTURE_RECTANGLE_ARB );
|
||||||
glBindTexture( GL_TEXTURE_RECTANGLE_ARB, 0 );
|
glBindTexture( GL_TEXTURE_RECTANGLE_ARB, 0 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,11 +38,16 @@ class SceneOpenGL
|
||||||
void paintSimpleScreen( QRegion damage, ToplevelList windows );
|
void paintSimpleScreen( QRegion damage, ToplevelList windows );
|
||||||
void paintBackground( QRegion damage );
|
void paintBackground( QRegion damage );
|
||||||
static QRegion infiniteRegion();
|
static QRegion infiniteRegion();
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PAINT_OPAQUE = 1 << 0,
|
||||||
|
PAINT_TRANSLUCENT = 1 << 1
|
||||||
|
};
|
||||||
typedef GLuint Texture;
|
typedef GLuint Texture;
|
||||||
GC gcroot;
|
GC gcroot;
|
||||||
Drawable buffer;
|
Drawable buffer;
|
||||||
GLXFBConfig fbcroot;
|
GLXFBConfig fbcroot;
|
||||||
bool root_db;
|
static bool root_db;
|
||||||
static GLXFBConfig fbcdrawable;
|
static GLXFBConfig fbcdrawable;
|
||||||
static GLXDrawable glxroot;
|
static GLXDrawable glxroot;
|
||||||
static GLXContext context;
|
static GLXContext context;
|
||||||
|
@ -67,7 +72,7 @@ class SceneOpenGL::Window
|
||||||
int y() const;
|
int y() const;
|
||||||
int width() const;
|
int width() const;
|
||||||
int height() const;
|
int height() const;
|
||||||
void paint( QRegion region );
|
void paint( QRegion region, int mask );
|
||||||
bool isVisible() const;
|
bool isVisible() const;
|
||||||
bool isOpaque() const;
|
bool isOpaque() const;
|
||||||
void bindTexture();
|
void bindTexture();
|
||||||
|
|
Loading…
Reference in a new issue