diff --git a/scene_opengl.cpp b/scene_opengl.cpp index 138a06250b..790ffa596c 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -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(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(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() diff --git a/scene_opengl.h b/scene_opengl.h index 5b7e802eb3..bab6ae3057 100644 --- a/scene_opengl.h +++ b/scene_opengl.h @@ -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