Scene OpenGL compiles with ES

It's mostly just ifdef away everything that cannot work.
Needs to be split into a scene_xgl and scene_egl.
master
Martin Gräßlin 14 years ago
parent 1947f67e80
commit 5fae85f2a5

@ -102,6 +102,7 @@ extern int currentRefreshRate();
// SceneOpenGL
//****************************************
#ifndef KWIN_HAVE_OPENGLES
// the configs used for the destination
GLXFBConfig SceneOpenGL::fbcbuffer_db;
GLXFBConfig SceneOpenGL::fbcbuffer_nondb;
@ -113,6 +114,7 @@ GLXContext SceneOpenGL::ctxdrawable;
// the destination drawable where the compositing is done
GLXDrawable SceneOpenGL::glxbuffer = None;
GLXDrawable SceneOpenGL::last_pixmap = None;
#endif
bool SceneOpenGL::tfp_mode; // using glXBindTexImageEXT (texture_from_pixmap)
bool SceneOpenGL::db; // destination drawable is double-buffered
bool SceneOpenGL::shm_mode;
@ -127,6 +129,7 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
, selfCheckDone( false )
, m_sceneShader( NULL )
{
#ifndef KWIN_HAVE_OPENGLES
if( !Extensions::glxAvailable())
{
kDebug( 1212 ) << "No glx extensions available";
@ -178,6 +181,7 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
else
qWarning() << "NO VSYNC! glXGetVideoSync(&uint) isn't 0 but" << glXGetVideoSync( &sync );
}
#endif
debug = qstrcmp( qgetenv( "KWIN_GL_DEBUG" ), "1" ) == 0;
@ -205,6 +209,7 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
}
}
#ifndef KWIN_HAVE_OPENGLES
// OpenGL scene setup
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
@ -243,6 +248,7 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
#endif
kDebug( 1212 ) << "DB:" << db << ", TFP:" << tfp_mode << ", SHM:" << shm_mode
<< ", Direct:" << bool( glXIsDirect( display(), ctxbuffer )) << endl;
#endif
init_ok = true;
}
@ -257,6 +263,7 @@ SceneOpenGL::~SceneOpenGL()
foreach( Window* w, windows )
delete w;
// do cleanup after initBuffer()
#ifndef KWIN_HAVE_OPENGLES
glXMakeCurrent( display(), None, NULL );
glXDestroyContext( display(), ctxbuffer );
if( wspace->overlayWindow())
@ -280,6 +287,7 @@ SceneOpenGL::~SceneOpenGL()
glXDestroyPixmap( display(), last_pixmap );
glXDestroyContext( display(), ctxdrawable );
}
#endif
delete m_sceneShader;
SceneOpenGL::EffectFrame::cleanup();
checkGLError( "Cleanup" );
@ -316,9 +324,13 @@ bool SceneOpenGL::selectMode()
bool SceneOpenGL::initTfp()
{
#ifdef KWIN_HAVE_OPENGLES
return false;
#else
if( glXBindTexImageEXT == NULL || glXReleaseTexImageEXT == NULL )
return false;
return true;
#endif
}
bool SceneOpenGL::initShm()
@ -375,6 +387,9 @@ void SceneOpenGL::cleanupShm()
bool SceneOpenGL::initRenderingContext()
{
#ifdef KWIN_HAVE_OPENGLES
return false;
#else
bool direct_rendering = options->glDirect;
if( !tfp_mode && !shm_mode )
direct_rendering = false; // fallback doesn't seem to work with direct rendering
@ -414,11 +429,15 @@ bool SceneOpenGL::initRenderingContext()
direct_rendering ? GL_TRUE : GL_FALSE );
}
return true;
#endif
}
// create destination buffer
bool SceneOpenGL::initBuffer()
{
#ifdef KWIN_HAVE_OPENGLES
return false;
#else
if( !initBufferConfigs())
return false;
if( fbcbuffer_db != NULL && wspace->createOverlay())
@ -461,11 +480,15 @@ bool SceneOpenGL::initBuffer()
kDebug( 1212 ) << "Buffer visual (depth " << visinfo_buffer->depth << "): 0x" << QString::number( vis_buffer, 16 );
XFree( visinfo_buffer );
return true;
#endif
}
// choose the best configs for the destination buffer
bool SceneOpenGL::initBufferConfigs()
{
#ifdef KWIN_HAVE_OPENGLES
return false;
#else
int cnt;
GLXFBConfig *fbconfigs = glXGetFBConfigs( display(), DefaultScreen( display() ), &cnt );
fbcbuffer_db = NULL;
@ -555,11 +578,15 @@ bool SceneOpenGL::initBufferConfigs()
kDebug( 1212 ) << "Drawable visual (depth " << i << "): 0x" << QString::number( vis_drawable, 16 );
}
return true;
#endif
}
// make a list of the best configs for windows by depth
bool SceneOpenGL::initDrawableConfigs()
{
#ifdef KWIN_HAVE_OPENGLES
return false;
#else
int cnt;
GLXFBConfig *fbconfigs = glXGetFBConfigs( display(), DefaultScreen( display() ), &cnt );
@ -684,6 +711,7 @@ bool SceneOpenGL::initDrawableConfigs()
return false;
}
return true;
#endif
}
// Test if compositing actually _really_ works, by creating a texture from a testing
@ -709,6 +737,7 @@ bool SceneOpenGL::selfCheck()
void SceneOpenGL::selfCheckSetup()
{
#ifndef KWIN_HAVE_OPENGLES
KXErrorHandler err;
QImage img( selfCheckWidth(), selfCheckHeight(), QImage::Format_RGB32 );
img.setPixel( 0, 0, QColor( Qt::red ).rgb());
@ -744,10 +773,14 @@ void SceneOpenGL::selfCheckSetup()
XDestroyWindow( display(), window );
}
err.error( true ); // just sync and discard
#endif
}
bool SceneOpenGL::selfCheckFinish()
{
#ifdef KWIN_HAVE_OPENGLES
return true;
#else
glXWaitGL();
KXErrorHandler err;
bool ok = true;
@ -783,12 +816,26 @@ bool SceneOpenGL::selfCheckFinish()
return true;
}
return ok;
#endif
}
// the entry function for painting
void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels )
{
QTime t = QTime::currentTime();
#ifdef KWIN_HAVE_OPENGLES
foreach( Toplevel* c, toplevels )
{
assert( windows.contains( c ));
stacking_order.append( windows[ c ] );
}
int mask = 0;
paintScreen( &mask, &damage ); // call generic implementation
flushBuffer( mask, damage );
// do cleanup
stacking_order.clear();
checkGLError( "PostPaint" );
#else
foreach( Toplevel* c, toplevels )
{
assert( windows.contains( c ));
@ -830,11 +877,13 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels )
// do cleanup
stacking_order.clear();
checkGLError( "PostPaint" );
#endif
}
// wait for vblank signal before painting
void SceneOpenGL::waitSync()
{ // NOTE that vsync has no effect with indirect rendering
#ifndef KWIN_HAVE_OPENGLES
if( waitSyncAvailable())
{
uint sync;
@ -842,11 +891,14 @@ void SceneOpenGL::waitSync()
glXGetVideoSync( &sync );
glXWaitVideoSync( 2, ( sync + 1 ) % 2, &sync );
}
#endif
}
// actually paint to the screen (double-buffer swap or copy from pixmap buffer)
void SceneOpenGL::flushBuffer( int mask, QRegion damage )
{
// TODO: write EGL variant
#ifndef KWIN_HAVE_OPENGLES
if( db )
{
if( mask & PAINT_SCREEN_REGION )
@ -906,12 +958,14 @@ void SceneOpenGL::flushBuffer( int mask, QRegion damage )
XCopyArea( display(), buffer, rootWindow(), gcroot, 0, 0, displayWidth(), displayHeight(), 0, 0 );
XFlush( display());
}
#endif
}
void SceneOpenGL::paintGenericScreen( int mask, ScreenPaintData data )
{
if( mask & PAINT_SCREEN_TRANSFORMED )
{ // apply screen transformations
#ifndef KWIN_HAVE_OPENGLES
glPushMatrix();
glTranslatef( data.xTranslate, data.yTranslate, data.zTranslate );
if( data.rotation )
@ -937,14 +991,21 @@ void SceneOpenGL::paintGenericScreen( int mask, ScreenPaintData data )
glTranslatef( -data.rotation->xRotationPoint, -data.rotation->yRotationPoint, -data.rotation->zRotationPoint );
}
glScalef( data.xScale, data.yScale, data.zScale );
#endif
}
Scene::paintGenericScreen( mask, data );
if( mask & PAINT_SCREEN_TRANSFORMED )
{
#ifndef KWIN_HAVE_OPENGLES
glPopMatrix();
#endif
}
}
void SceneOpenGL::paintBackground( QRegion region )
{
// TODO: write for EGL
#ifndef KWIN_HAVE_OPENGLES
PaintClipper pc( region );
if( !PaintClipper::clip())
{
@ -971,6 +1032,7 @@ void SceneOpenGL::paintBackground( QRegion region )
glEnd();
}
glPopAttrib();
#endif
}
void SceneOpenGL::windowAdded( Toplevel* c )
@ -1051,7 +1113,9 @@ SceneOpenGL::Texture::~Texture()
void SceneOpenGL::Texture::init()
{
#ifndef KWIN_HAVE_OPENGLES
glxpixmap = None;
#endif
}
void SceneOpenGL::Texture::createTexture()
@ -1066,6 +1130,8 @@ void SceneOpenGL::Texture::discard()
GLTexture::discard();
}
// TODO: write for EGL
#ifndef KWIN_HAVE_OPENGLES
void SceneOpenGL::Texture::release()
{
if( tfp_mode && glxpixmap != None )
@ -1076,7 +1142,10 @@ void SceneOpenGL::Texture::release()
glxpixmap = None;
}
}
#endif
// TODO: write for EGL
#ifndef KWIN_HAVE_OPENGLES
void SceneOpenGL::Texture::findTarget()
{
unsigned int new_target = 0;
@ -1110,6 +1179,7 @@ void SceneOpenGL::Texture::findTarget()
abort();
}
}
#endif
QRegion SceneOpenGL::Texture::optimizeBindDamage( const QRegion& reg, int limit )
{
@ -1127,6 +1197,8 @@ QRegion SceneOpenGL::Texture::optimizeBindDamage( const QRegion& reg, int limit
return reg;
}
// TODO: write EGL variant
#ifndef KWIN_HAVE_OPENGLES
bool SceneOpenGL::Texture::load( const Pixmap& pix, const QSize& size,
int depth, QRegion region )
{
@ -1310,6 +1382,7 @@ bool SceneOpenGL::Texture::load( const Pixmap& pix, const QSize& size,
#endif
return true;
}
#endif
bool SceneOpenGL::Texture::load( const Pixmap& pix, const QSize& size,
int depth )
@ -1339,21 +1412,26 @@ void SceneOpenGL::Texture::bind()
glBindTexture( mTarget, mTexture );
if( tfp_mode && options->glStrictBinding )
{
#ifndef KWIN_HAVE_OPENGLES
assert( glxpixmap != None );
glXReleaseTexImageEXT( display(), glxpixmap, GLX_FRONT_LEFT_EXT );
glXBindTexImageEXT( display(), glxpixmap, GLX_FRONT_LEFT_EXT, NULL );
setDirty(); // Mipmaps have to be regenerated after updating the texture
setDirty(); // Mipmaps have to be regenerated after updating the texture
#endif
}
enableFilter();
#ifndef KWIN_HAVE_OPENGLES
if( hasGLVersion( 1, 4, 0 ))
{
// Lod bias makes the trilinear-filtered texture look a bit sharper
glTexEnvf( GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -1.0f );
}
#endif
}
void SceneOpenGL::Texture::unbind()
{
#ifndef KWIN_HAVE_OPENGLES
if( hasGLVersion( 1, 4, 0 ))
{
glTexEnvf( GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 0.0f );
@ -1365,6 +1443,7 @@ void SceneOpenGL::Texture::unbind()
glXReleaseTexImageEXT( display(), glxpixmap, GLX_FRONT_LEFT_EXT );
}
#endif
GLTexture::unbind();
}
@ -1460,7 +1539,6 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat
return;
if( !bindTexture())
return;
glPushMatrix();
// set texture filter
if( options->glSmoothScale != 0 ) // default to yes
{
@ -1498,6 +1576,8 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat
}
if( !sceneShader )
{
#ifndef KWIN_HAVE_OPENGLES
glPushMatrix();
glTranslatef( x, y, z );
if(( mask & PAINT_WINDOW_TRANSFORMED ) && ( data.xScale != 1 || data.yScale != 1 || data.zScale != 1 ))
glScalef( data.xScale, data.yScale, data.zScale );
@ -1522,6 +1602,7 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat
glRotatef( data.rotation->angle, xAxis, yAxis, zAxis );
glTranslatef( -data.rotation->xRotationPoint, -data.rotation->yRotationPoint, -data.rotation->zRotationPoint );
}
#endif
}
region.translate( toplevel->x(), toplevel->y() ); // Back to screen coords
@ -1613,12 +1694,14 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat
restoreStates( Content, data.opacity * data.contents_opacity, data.brightness, data.saturation, data.shader );
texture.disableUnnormalizedTexCoords();
texture.unbind();
#ifndef KWIN_HAVE_OPENGLES
if( static_cast<SceneOpenGL*>(scene)->debug )
{
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
renderQuads( mask, region, data.quads.select( WindowQuadContents ));
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
}
#endif
}
if( sceneShader )
@ -1626,8 +1709,10 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat
data.shader->unbind();
data.shader = NULL;
}
glPopMatrix();
#ifndef KWIN_HAVE_OPENGLES
else
glPopMatrix();
#endif
}
void SceneOpenGL::Window::paintDecoration( const QPixmap* decoration, TextureType decorationType, const QRegion& region, const QRect& rect, const WindowPaintData& data, const WindowQuadList& quads, bool updateDeco )
@ -1685,12 +1770,14 @@ void SceneOpenGL::Window::paintDecoration( const QPixmap* decoration, TextureTyp
SceneOpenGL::Window::decorationVertices->render( region, GL_TRIANGLES );
restoreStates( decorationType, data.opacity * data.decoration_opacity, data.brightness, data.saturation, data.shader );
decorationTexture->unbind();
#ifndef KWIN_HAVE_OPENGLES
if( static_cast<SceneOpenGL*>(scene)->debug )
{
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
SceneOpenGL::Window::decorationVertices->render( region, GL_TRIANGLES );
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
}
#endif
}
void SceneOpenGL::Window::makeDecorationArrays( const WindowQuadList& quads, const QRect& rect ) const
@ -1757,7 +1844,9 @@ void SceneOpenGL::Window::prepareStates( TextureType type, double opacity, doubl
void SceneOpenGL::Window::prepareShaderRenderStates( TextureType type, double opacity, double brightness, double saturation, GLShader* shader )
{
// setup blending of transparent windows
#ifndef KWIN_HAVE_OPENGLES
glPushAttrib( GL_ENABLE_BIT );
#endif
bool opaque = isOpaque() && opacity == 1.0;
bool alpha = toplevel->hasAlpha() || type != Content;
if( type != Content )
@ -1791,6 +1880,7 @@ void SceneOpenGL::Window::prepareShaderRenderStates( TextureType type, double op
void SceneOpenGL::Window::prepareRenderStates( TextureType type, double opacity, double brightness, double saturation )
{
#ifndef KWIN_HAVE_OPENGLES
Texture* tex;
bool alpha = false;
bool opaque = true;
@ -1952,6 +2042,7 @@ void SceneOpenGL::Window::prepareRenderStates( TextureType type, double opacity,
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_CONSTANT );
glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant );
}
#endif
}
void SceneOpenGL::Window::restoreStates( TextureType type, double opacity, double brightness, double saturation, GLShader* shader )
@ -1964,16 +2055,24 @@ void SceneOpenGL::Window::restoreStates( TextureType type, double opacity, doubl
void SceneOpenGL::Window::restoreShaderRenderStates( TextureType type, double opacity, double brightness, double saturation, GLShader* shader )
{
Q_UNUSED( type );
Q_UNUSED( opacity );
Q_UNUSED( brightness );
Q_UNUSED( saturation );
Q_UNUSED( shader );
bool opaque = isOpaque() && opacity == 1.0;
if( type != Content )
opaque = false;
if( !opaque )
{
glDisable( GL_BLEND );
}
#ifndef KWIN_HAVE_OPENGLES
glPopAttrib(); // ENABLE_BIT
#endif
}
void SceneOpenGL::Window::restoreRenderStates( TextureType type, double opacity, double brightness, double saturation )
{
#ifndef KWIN_HAVE_OPENGLES
Texture* tex;
switch( type )
{
@ -2012,6 +2111,7 @@ void SceneOpenGL::Window::restoreRenderStates( TextureType type, double opacity,
glColor4f( 0, 0, 0, 0 );
glPopAttrib(); // ENABLE_BIT
#endif
}
//****************************************
@ -2131,13 +2231,18 @@ void SceneOpenGL::EffectFrame::render( QRegion region, double opacity, double fr
shader->setUniform("textureHeight", 1.0f);
}
#ifndef KWIN_HAVE_OPENGLES
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TEXTURE_BIT );
#endif
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
#ifndef KWIN_HAVE_OPENGLES
if( !shader )
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
// TODO: drop the push matrix
glPushMatrix();
#endif
// Render the actual frame
if( m_effectFrame->style() == EffectFrameUnstyled )
@ -2251,8 +2356,10 @@ void SceneOpenGL::EffectFrame::render( QRegion region, double opacity, double fr
if( shader )
shader->setUniform( "opacity", (float)(opacity * frameOpacity) );
#ifndef KWIN_HAVE_OPENGLES
else
glColor4f( 0.0, 0.0, 0.0, opacity * frameOpacity );
#endif
m_unstyledTexture->bind();
const QPoint pt = m_effectFrame->geometry().topLeft();
@ -2280,9 +2387,10 @@ void SceneOpenGL::EffectFrame::render( QRegion region, double opacity, double fr
if( shader )
shader->setUniform( "opacity", (float)(opacity * frameOpacity) );
#ifndef KWIN_HAVE_OPENGLES
else
glColor4f( 1.0, 1.0, 1.0, opacity * frameOpacity );
#endif
m_texture->bind();
qreal left, top, right, bottom;
m_effectFrame->frame().getMargins( left, top, right, bottom ); // m_geometry is the inner geometry
@ -2314,23 +2422,29 @@ void SceneOpenGL::EffectFrame::render( QRegion region, double opacity, double fr
{
if( shader )
shader->setUniform( "opacity", (float)opacity * (1.0f - (float)m_effectFrame->crossFadeProgress()) );
#ifndef KWIN_HAVE_OPENGLES
else
glColor4f( 1.0, 1.0, 1.0, opacity * (1.0 - m_effectFrame->crossFadeProgress()) );
#endif
m_oldIconTexture->bind();
m_oldIconTexture->render( region, QRect( topLeft, m_effectFrame->iconSize() ));
m_oldIconTexture->unbind();
if( shader )
shader->setUniform( "opacity", (float)opacity * (float)m_effectFrame->crossFadeProgress() );
#ifndef KWIN_HAVE_OPENGLES
else
glColor4f( 1.0, 1.0, 1.0, opacity * m_effectFrame->crossFadeProgress() );
#endif
}
else
{
if( shader )
shader->setUniform( "opacity", (float)opacity );
#ifndef KWIN_HAVE_OPENGLES
else
glColor4f( 1.0, 1.0, 1.0, opacity );
#endif
}
if( !m_iconTexture ) // lazy creation
@ -2351,23 +2465,29 @@ void SceneOpenGL::EffectFrame::render( QRegion region, double opacity, double fr
{
if( shader )
shader->setUniform( "opacity", (float)opacity * (1.0f - (float)m_effectFrame->crossFadeProgress()) );
#ifndef KWIN_HAVE_OPENGLES
else
glColor4f( 1.0, 1.0, 1.0, opacity * (1.0 - m_effectFrame->crossFadeProgress()) );
#endif
m_oldTextTexture->bind();
m_oldTextTexture->render( region, m_effectFrame->geometry(), sceneShader );
m_oldTextTexture->unbind();
if( shader )
shader->setUniform( "opacity", (float)opacity * (float)m_effectFrame->crossFadeProgress() );
#ifndef KWIN_HAVE_OPENGLES
else
glColor4f( 1.0, 1.0, 1.0, opacity * m_effectFrame->crossFadeProgress() );
#endif
}
else
{
if( shader )
shader->setUniform( "opacity", (float)opacity );
#ifndef KWIN_HAVE_OPENGLES
else
glColor4f( 1.0, 1.0, 1.0, opacity );
#endif
}
if( !m_textTexture ) // Lazy creation
updateTextTexture();
@ -2378,9 +2498,11 @@ void SceneOpenGL::EffectFrame::render( QRegion region, double opacity, double fr
if( shader )
shader->unbind();
glDisable( GL_BLEND );
#ifndef KWIN_HAVE_OPENGLES
glPopMatrix();
glPopAttrib();
#endif
}
void SceneOpenGL::EffectFrame::updateTexture()

@ -73,15 +73,20 @@ class SceneOpenGL
class FBConfigInfo
{
public:
#ifndef KWIN_HAVE_OPENGLES
GLXFBConfig fbconfig;
#endif
int bind_texture_format;
int texture_targets;
int y_inverted;
int mipmap;
};
#ifndef KWIN_HAVE_OPENGLES
Drawable buffer;
GLXFBConfig fbcbuffer;
#endif
static bool db;
#ifndef KWIN_HAVE_OPENGLES
static GLXFBConfig fbcbuffer_db;
static GLXFBConfig fbcbuffer_nondb;
static FBConfigInfo fbcdrawableinfo[ 32 + 1 ];
@ -89,6 +94,7 @@ class SceneOpenGL
static GLXContext ctxbuffer;
static GLXContext ctxdrawable;
static GLXDrawable last_pixmap; // for a workaround in bindTexture()
#endif
static bool tfp_mode;
static bool shm_mode;
QHash< Toplevel*, Window* > windows;
@ -128,7 +134,9 @@ class SceneOpenGL::Texture
private:
void init();
#ifndef KWIN_HAVE_OPENGLES
GLXPixmap glxpixmap; // the glx pixmap the texture is bound to, only for tfp_mode
#endif
};
class SceneOpenGL::Window

Loading…
Cancel
Save