/******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright (C) 2006 Lubos Lunak This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ #ifndef KWIN_SCENE_OPENGL_H #define KWIN_SCENE_OPENGL_H #include "scene.h" #include "kwinglutils.h" #ifdef KWIN_HAVE_OPENGL_COMPOSITING #ifdef HAVE_XSHM #include #endif namespace KWin { class SceneOpenGL : public Scene { public: class EffectFrame; class Texture; class Window; SceneOpenGL( Workspace* ws ); virtual ~SceneOpenGL(); virtual bool initFailed() const; virtual CompositingType compositingType() const { return OpenGLCompositing; } virtual void paint( QRegion damage, ToplevelList windows ); virtual void windowGeometryShapeChanged( Toplevel* ); virtual void windowOpacityChanged( Toplevel* ); virtual void windowAdded( Toplevel* ); virtual void windowClosed( Toplevel*, Deleted* ); virtual void windowDeleted( Deleted* ); protected: virtual void paintGenericScreen( int mask, ScreenPaintData data ); virtual void paintBackground( QRegion region ); private: bool selectMode(); bool initTfp(); bool initShm(); void cleanupShm(); bool initBuffer(); bool initRenderingContext(); bool initBufferConfigs(); bool initDrawableConfigs(); void waitSync(); void flushBuffer( int mask, QRegion damage ); bool selfCheck(); void selfCheckSetup(); bool selfCheckFinish(); GC gcroot; class FBConfigInfo { public: GLXFBConfig fbconfig; int bind_texture_format; int y_inverted; int mipmap; }; Drawable buffer; GLXFBConfig fbcbuffer; static bool db; static GLXFBConfig fbcbuffer_db; static GLXFBConfig fbcbuffer_nondb; static FBConfigInfo fbcdrawableinfo[ 32 + 1 ]; static GLXDrawable glxbuffer; static GLXContext ctxbuffer; static GLXContext ctxdrawable; static GLXDrawable last_pixmap; // for a workaround in bindTexture() static bool tfp_mode; static bool shm_mode; QHash< Toplevel*, Window* > windows; #ifdef HAVE_XSHM static XShmSegmentInfo shm; #endif bool init_ok; bool selfCheckDone; }; class SceneOpenGL::Texture : public GLTexture { public: Texture(); Texture( const Pixmap& pix, const QSize& size, int depth ); virtual ~Texture(); using GLTexture::load; virtual bool load( const Pixmap& pix, const QSize& size, int depth, QRegion region ); virtual bool load( const Pixmap& pix, const QSize& size, int depth ); virtual bool load( const QImage& image, GLenum target = GL_TEXTURE_2D ); virtual bool load( const QPixmap& pixmap, GLenum target = GL_TEXTURE_2D ); virtual void discard(); virtual void release(); // undo the tfp_mode binding virtual void bind(); virtual void unbind(); protected: void findTarget(); QRegion optimizeBindDamage( const QRegion& reg, int limit ); void createTexture(); private: void init(); GLXPixmap bound_glxpixmap; // the glx pixmap the texture is bound to, only for tfp_mode }; class SceneOpenGL::Window : public Scene::Window { public: Window( Toplevel* c ); virtual ~Window(); virtual void performPaint( int mask, QRegion region, WindowPaintData data ); virtual void pixmapDiscarded(); bool bindTexture(); void discardTexture(); void checkTextureSize(); protected: enum TextureType { Content, DecorationTop, DecorationLeft, DecorationRight, DecorationBottom }; void paintDecoration( const QPixmap* decoration, TextureType decorationType, const QRegion& region, const QRect& rect, const WindowPaintData& data, const WindowQuadList& quads, bool updateDeco ); void makeDecorationArrays( float** vertices, float** texcoords, const WindowQuadList& quads, const QRect& rect ) const; void renderQuads( int mask, const QRegion& region, const WindowQuadList& quads ); void prepareStates( TextureType type, double opacity, double brightness, double saturation, GLShader* shader ); void prepareRenderStates( TextureType type, double opacity, double brightness, double saturation ); void prepareShaderRenderStates( TextureType type, double opacity, double brightness, double saturation, GLShader* shader ); void restoreStates( TextureType type, double opacity, double brightness, double saturation, GLShader* shader ); void restoreRenderStates( TextureType type, double opacity, double brightness, double saturation ); void restoreShaderRenderStates( TextureType type, double opacity, double brightness, double saturation, GLShader* shader ); private: Texture texture; Texture topTexture; Texture leftTexture; Texture rightTexture; Texture bottomTexture; }; class SceneOpenGL::EffectFrame : public Scene::EffectFrame { public: EffectFrame( EffectFrameImpl* frame ); virtual ~EffectFrame(); virtual void free(); virtual void freeTextFrame(); virtual void render(QRegion region, double opacity, double frameOpacity); static void cleanup(); private: void updateTexture(); void updateTextTexture(); GLTexture* m_texture; GLTexture* m_textTexture; static GLTexture* m_unstyledTexture; static void updateUnstyledTexture(); // Update OpenGL unstyled frame texture }; } // namespace #endif #endif