Another attempt at self-check, this time done directly during setup
(so that it can fail immediately). svn path=/trunk/KDE/kdebase/workspace/; revision=859960
This commit is contained in:
parent
cfb0a0584d
commit
8eedfa3456
4 changed files with 70 additions and 31 deletions
|
@ -433,10 +433,7 @@ void Workspace::setupOverlay( Window w )
|
||||||
assert( overlay != None );
|
assert( overlay != None );
|
||||||
assert( Extensions::shapeInputAvailable());
|
assert( Extensions::shapeInputAvailable());
|
||||||
XSetWindowBackgroundPixmap( display(), overlay, None );
|
XSetWindowBackgroundPixmap( display(), overlay, None );
|
||||||
XRectangle rec = { 0, 0, displayWidth(), displayHeight() };
|
setOverlayShape( QRect( 0, 0, displayWidth(), displayHeight()));
|
||||||
XShapeCombineRectangles( display(), overlay, ShapeBounding, 0, 0, &rec, 1, ShapeSet, Unsorted );
|
|
||||||
XShapeCombineRectangles( display(), overlay, ShapeInput, 0, 0, NULL, 0, ShapeSet, Unsorted );
|
|
||||||
overlay_shape = QRegion( 0, 0, displayWidth(), displayHeight());
|
|
||||||
if( w != None )
|
if( w != None )
|
||||||
{
|
{
|
||||||
XSetWindowBackgroundPixmap( display(), w, None );
|
XSetWindowBackgroundPixmap( display(), w, None );
|
||||||
|
@ -455,6 +452,34 @@ void Workspace::showOverlay()
|
||||||
overlay_shown = true;
|
overlay_shown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Workspace::hideOverlay()
|
||||||
|
{
|
||||||
|
assert( overlay != None );
|
||||||
|
XUnmapWindow( display(), overlay );
|
||||||
|
overlay_shown = false;
|
||||||
|
setOverlayShape( QRect( 0, 0, displayWidth(), displayHeight()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Workspace::setOverlayShape( const QRegion& reg )
|
||||||
|
{
|
||||||
|
QVector< QRect > rects = reg.rects();
|
||||||
|
XRectangle* xrects = new XRectangle[ rects.count() ];
|
||||||
|
for( int i = 0;
|
||||||
|
i < rects.count();
|
||||||
|
++i )
|
||||||
|
{
|
||||||
|
xrects[ i ].x = rects[ i ].x();
|
||||||
|
xrects[ i ].y = rects[ i ].y();
|
||||||
|
xrects[ i ].width = rects[ i ].width();
|
||||||
|
xrects[ i ].height = rects[ i ].height();
|
||||||
|
}
|
||||||
|
XShapeCombineRectangles( display(), overlay, ShapeBounding, 0, 0,
|
||||||
|
xrects, rects.count(), ShapeSet, Unsorted );
|
||||||
|
delete[] xrects;
|
||||||
|
XShapeCombineRectangles( display(), overlay, ShapeInput, 0, 0, NULL, 0, ShapeSet, Unsorted );
|
||||||
|
overlay_shape = reg;
|
||||||
|
}
|
||||||
|
|
||||||
void Workspace::destroyOverlay()
|
void Workspace::destroyOverlay()
|
||||||
{
|
{
|
||||||
if( overlay == None )
|
if( overlay == None )
|
||||||
|
|
|
@ -118,7 +118,6 @@ XShmSegmentInfo SceneOpenGL::shm;
|
||||||
SceneOpenGL::SceneOpenGL( Workspace* ws )
|
SceneOpenGL::SceneOpenGL( Workspace* ws )
|
||||||
: Scene( ws )
|
: Scene( ws )
|
||||||
, init_ok( false )
|
, init_ok( false )
|
||||||
, selfCheckDone( false )
|
|
||||||
{
|
{
|
||||||
if( !Extensions::glxAvailable())
|
if( !Extensions::glxAvailable())
|
||||||
{
|
{
|
||||||
|
@ -177,17 +176,19 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
|
||||||
glFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
|
glFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
|
||||||
glMatrixMode( GL_MODELVIEW );
|
glMatrixMode( GL_MODELVIEW );
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
float scaleFactor = 1.1 * tan( fovy * M_PI / 360.0f )/ymax;
|
||||||
|
glTranslatef( xmin*scaleFactor, ymax*scaleFactor, -1.1 );
|
||||||
|
glScalef( (xmax-xmin)*scaleFactor/displayWidth(), -(ymax-ymin)*scaleFactor/displayHeight(), 0.001 );
|
||||||
if( checkGLError( "Init" ))
|
if( checkGLError( "Init" ))
|
||||||
{
|
{
|
||||||
kError( 1212 ) << "OpenGL compositing setup failed";
|
kError( 1212 ) << "OpenGL compositing setup failed";
|
||||||
return; // error
|
return; // error
|
||||||
}
|
}
|
||||||
|
if( !selfCheck())
|
||||||
|
return;
|
||||||
kDebug( 1212 ) << "DB:" << db << ", TFP:" << tfp_mode << ", SHM:" << shm_mode
|
kDebug( 1212 ) << "DB:" << db << ", TFP:" << tfp_mode << ", SHM:" << shm_mode
|
||||||
<< ", Direct:" << bool( glXIsDirect( display(), ctxbuffer )) << endl;
|
<< ", Direct:" << bool( glXIsDirect( display(), ctxbuffer )) << endl;
|
||||||
init_ok = true;
|
init_ok = true;
|
||||||
float scaleFactor = 1.1 * tan( fovy * M_PI / 360.0f )/ymax;
|
|
||||||
glTranslatef( xmin*scaleFactor, ymax*scaleFactor, -1.1 );
|
|
||||||
glScalef( (xmax-xmin)*scaleFactor/displayWidth(), -(ymax-ymin)*scaleFactor/displayHeight(), 0.001 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneOpenGL::~SceneOpenGL()
|
SceneOpenGL::~SceneOpenGL()
|
||||||
|
@ -625,7 +626,7 @@ bool SceneOpenGL::initDrawableConfigs()
|
||||||
// window, drawing it on the screen, reading the contents back and comparing. This
|
// window, drawing it on the screen, reading the contents back and comparing. This
|
||||||
// should test whether compositing really works.
|
// should test whether compositing really works.
|
||||||
// It would be still nice to check somehow if compositing is not awfully slow.
|
// It would be still nice to check somehow if compositing is not awfully slow.
|
||||||
void SceneOpenGL::selfCheckSetup( QRegion& damage )
|
bool SceneOpenGL::selfCheck()
|
||||||
{
|
{
|
||||||
QImage img( 5, 1, QImage::Format_RGB32 );
|
QImage img( 5, 1, QImage::Format_RGB32 );
|
||||||
img.setPixel( 0, 0, QColor( Qt::red ).rgb());
|
img.setPixel( 0, 0, QColor( Qt::red ).rgb());
|
||||||
|
@ -634,7 +635,16 @@ void SceneOpenGL::selfCheckSetup( QRegion& damage )
|
||||||
img.setPixel( 3, 0, QColor( Qt::white ).rgb());
|
img.setPixel( 3, 0, QColor( Qt::white ).rgb());
|
||||||
img.setPixel( 4, 0, QColor( Qt::black ).rgb());
|
img.setPixel( 4, 0, QColor( Qt::black ).rgb());
|
||||||
QPixmap pix = QPixmap::fromImage( img );
|
QPixmap pix = QPixmap::fromImage( img );
|
||||||
foreach( const QPoint& p, selfCheckPoints())
|
QList< QPoint > points = selfCheckPoints();
|
||||||
|
QRegion reg;
|
||||||
|
foreach( const QPoint& p, points )
|
||||||
|
reg |= QRect( p, pix.size());
|
||||||
|
if( wspace->overlayWindow())
|
||||||
|
{ // avoid covering the whole screen too soon
|
||||||
|
wspace->setOverlayShape( reg );
|
||||||
|
wspace->showOverlay();
|
||||||
|
}
|
||||||
|
foreach( const QPoint& p, points )
|
||||||
{
|
{
|
||||||
XSetWindowAttributes wa;
|
XSetWindowAttributes wa;
|
||||||
wa.override_redirect = True;
|
wa.override_redirect = True;
|
||||||
|
@ -643,7 +653,10 @@ void SceneOpenGL::selfCheckSetup( QRegion& damage )
|
||||||
XSetWindowBackgroundPixmap( display(), window, pix.handle());
|
XSetWindowBackgroundPixmap( display(), window, pix.handle());
|
||||||
XClearWindow( display(), window );
|
XClearWindow( display(), window );
|
||||||
XMapWindow( display(), window );
|
XMapWindow( display(), window );
|
||||||
XMoveWindow( display(), window, p.x(), p.y());
|
// move the window one down to where the result will be rendered too, just in case
|
||||||
|
// the render would fail completely and eventual check would try to read this window's contents
|
||||||
|
XMoveWindow( display(), window, p.x() + 1, p.y());
|
||||||
|
XCompositeRedirectWindow( display(), window, CompositeRedirectManual );
|
||||||
Pixmap wpix = XCompositeNameWindowPixmap( display(), window );
|
Pixmap wpix = XCompositeNameWindowPixmap( display(), window );
|
||||||
glXWaitX();
|
glXWaitX();
|
||||||
Texture texture;
|
Texture texture;
|
||||||
|
@ -651,23 +664,23 @@ void SceneOpenGL::selfCheckSetup( QRegion& damage )
|
||||||
texture.bind();
|
texture.bind();
|
||||||
QRect rect( p.x(), p.y(), 5, 1 );
|
QRect rect( p.x(), p.y(), 5, 1 );
|
||||||
texture.render( infiniteRegion(), rect );
|
texture.render( infiniteRegion(), rect );
|
||||||
Workspace::self()->addRepaint( rect );
|
|
||||||
texture.unbind();
|
texture.unbind();
|
||||||
glXWaitGL();
|
glXWaitGL();
|
||||||
XFreePixmap( display(), wpix );
|
XFreePixmap( display(), wpix );
|
||||||
damage |= rect;
|
|
||||||
XDestroyWindow( display(), window );
|
XDestroyWindow( display(), window );
|
||||||
}
|
}
|
||||||
}
|
flushBuffer( PAINT_SCREEN_REGION, reg );
|
||||||
|
|
||||||
void SceneOpenGL::selfCheckFinish()
|
|
||||||
{
|
|
||||||
glXWaitGL();
|
glXWaitGL();
|
||||||
selfCheckDone = true;
|
bool ok = true;
|
||||||
foreach( const QPoint& p, selfCheckPoints())
|
foreach( const QPoint& p, points )
|
||||||
{
|
{
|
||||||
QPixmap pix = QPixmap::grabWindow( rootWindow(), p.x(), p.y(), 5, 1 );
|
QPixmap pix = QPixmap::grabWindow( rootWindow(), p.x(), p.y(), 5, 1 );
|
||||||
QImage img = pix.toImage();
|
QImage img = pix.toImage();
|
||||||
|
// kdDebug() << "P:" << QColor( img.pixel( 0, 0 )).name();
|
||||||
|
// kdDebug() << "P:" << QColor( img.pixel( 1, 0 )).name();
|
||||||
|
// kdDebug() << "P:" << QColor( img.pixel( 2, 0 )).name();
|
||||||
|
// kdDebug() << "P:" << QColor( img.pixel( 3, 0 )).name();
|
||||||
|
// kdDebug() << "P:" << QColor( img.pixel( 4, 0 )).name();
|
||||||
if( img.pixel( 0, 0 ) != QColor( Qt::red ).rgb()
|
if( img.pixel( 0, 0 ) != QColor( Qt::red ).rgb()
|
||||||
|| img.pixel( 1, 0 ) != QColor( Qt::green ).rgb()
|
|| img.pixel( 1, 0 ) != QColor( Qt::green ).rgb()
|
||||||
|| img.pixel( 2, 0 ) != QColor( Qt::blue ).rgb()
|
|| img.pixel( 2, 0 ) != QColor( Qt::blue ).rgb()
|
||||||
|
@ -675,11 +688,15 @@ void SceneOpenGL::selfCheckFinish()
|
||||||
|| img.pixel( 4, 0 ) != QColor( Qt::black ).rgb())
|
|| img.pixel( 4, 0 ) != QColor( Qt::black ).rgb())
|
||||||
{
|
{
|
||||||
kError( 1212 ) << "Compositing self-check failed, disabling compositing.";
|
kError( 1212 ) << "Compositing self-check failed, disabling compositing.";
|
||||||
QTimer::singleShot( 0, Workspace::self(), SLOT( finishCompositing()));
|
ok = false;
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kDebug( 1212 ) << "Compositing self-check passed.";
|
if( wspace->overlayWindow())
|
||||||
|
wspace->hideOverlay();
|
||||||
|
if( ok )
|
||||||
|
kDebug( 1212 ) << "Compositing self-check passed.";
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList< QPoint > SceneOpenGL::selfCheckPoints() const
|
QList< QPoint > SceneOpenGL::selfCheckPoints() const
|
||||||
|
@ -691,7 +708,8 @@ QList< QPoint > SceneOpenGL::selfCheckPoints() const
|
||||||
++screen )
|
++screen )
|
||||||
{ // test top-left and bottom-right of every screen
|
{ // test top-left and bottom-right of every screen
|
||||||
ret.append( qApp->desktop()->screenGeometry( screen ).topLeft());
|
ret.append( qApp->desktop()->screenGeometry( screen ).topLeft());
|
||||||
ret.append( qApp->desktop()->screenGeometry( screen ).bottomRight() + QPoint( -5 + 1, -1 + 1 ));
|
ret.append( qApp->desktop()->screenGeometry( screen ).bottomRight() + QPoint( -5 + 1, -1 + 1 )
|
||||||
|
+ QPoint( -1, 0 )); // intentionally moved one up, since the source windows will be one down
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -719,11 +737,7 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels )
|
||||||
ungrabXServer(); // ungrab before flushBuffer(), it may wait for vsync
|
ungrabXServer(); // ungrab before flushBuffer(), it may wait for vsync
|
||||||
if( wspace->overlayWindow()) // show the window only after the first pass, since
|
if( wspace->overlayWindow()) // show the window only after the first pass, since
|
||||||
wspace->showOverlay(); // that pass may take long
|
wspace->showOverlay(); // that pass may take long
|
||||||
if( !selfCheckDone )
|
|
||||||
selfCheckSetup( damage );
|
|
||||||
flushBuffer( mask, damage );
|
flushBuffer( mask, damage );
|
||||||
if( !selfCheckDone )
|
|
||||||
selfCheckFinish();
|
|
||||||
// do cleanup
|
// do cleanup
|
||||||
stacking_order.clear();
|
stacking_order.clear();
|
||||||
checkGLError( "PostPaint" );
|
checkGLError( "PostPaint" );
|
||||||
|
|
|
@ -64,8 +64,7 @@ class SceneOpenGL
|
||||||
bool initDrawableConfigs();
|
bool initDrawableConfigs();
|
||||||
void waitSync();
|
void waitSync();
|
||||||
void flushBuffer( int mask, QRegion damage );
|
void flushBuffer( int mask, QRegion damage );
|
||||||
void selfCheckSetup( QRegion& damage );
|
bool selfCheck();
|
||||||
void selfCheckFinish();
|
|
||||||
QList< QPoint > selfCheckPoints() const;
|
QList< QPoint > selfCheckPoints() const;
|
||||||
GC gcroot;
|
GC gcroot;
|
||||||
class FBConfigInfo
|
class FBConfigInfo
|
||||||
|
@ -93,7 +92,6 @@ class SceneOpenGL
|
||||||
static XShmSegmentInfo shm;
|
static XShmSegmentInfo shm;
|
||||||
#endif
|
#endif
|
||||||
bool init_ok;
|
bool init_ok;
|
||||||
bool selfCheckDone;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SceneOpenGL::Texture
|
class SceneOpenGL::Texture
|
||||||
|
|
|
@ -327,6 +327,8 @@ class Workspace : public QObject, public KDecorationDefines
|
||||||
// init overlay and the destination window in it
|
// init overlay and the destination window in it
|
||||||
void setupOverlay( Window window );
|
void setupOverlay( Window window );
|
||||||
void showOverlay();
|
void showOverlay();
|
||||||
|
void hideOverlay(); // hides and resets overlay window
|
||||||
|
void setOverlayShape( const QRegion& reg );
|
||||||
// destroys XComposite overlay window
|
// destroys XComposite overlay window
|
||||||
void destroyOverlay();
|
void destroyOverlay();
|
||||||
Window overlayWindow();
|
Window overlayWindow();
|
||||||
|
@ -489,7 +491,6 @@ class Workspace : public QObject, public KDecorationDefines
|
||||||
void slotReloadConfig();
|
void slotReloadConfig();
|
||||||
void setPopupClientOpacity( QAction* action );
|
void setPopupClientOpacity( QAction* action );
|
||||||
void setupCompositing();
|
void setupCompositing();
|
||||||
void finishCompositing();
|
|
||||||
void performCompositing();
|
void performCompositing();
|
||||||
void lostCMSelection();
|
void lostCMSelection();
|
||||||
void updateElectricBorders();
|
void updateElectricBorders();
|
||||||
|
@ -573,6 +574,7 @@ class Workspace : public QObject, public KDecorationDefines
|
||||||
|
|
||||||
void updateClientArea( bool force );
|
void updateClientArea( bool force );
|
||||||
|
|
||||||
|
void finishCompositing();
|
||||||
bool windowRepaintsPending() const;
|
bool windowRepaintsPending() const;
|
||||||
void setCompositeTimer();
|
void setCompositeTimer();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue