From b28effff23f1593d46f5fb8625e70e08e0ca2e9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Wed, 19 Jun 2013 12:26:34 +0200 Subject: [PATCH] A Scene doesn't need to use an X11 Overlay Window Only the X based Scenes need an overlay window, so the Compositor doesn't need to check for it in the Wayland case. OverlayWindow is moved from OpenGLBackend to the sub classes which need to provide it. --- composite.cpp | 6 +++--- egl_wayland_backend.cpp | 5 +++++ egl_wayland_backend.h | 1 + eglonxbackend.cpp | 15 +++++++++++++++ eglonxbackend.h | 6 ++++++ glxbackend.cpp | 15 +++++++++++++++ glxbackend.h | 6 ++++++ scene.cpp | 3 +++ scene.h | 4 ++++ scene_opengl.cpp | 12 ++++++------ scene_opengl.h | 15 ++++++++------- scene_xrender.cpp | 5 +++++ scene_xrender.h | 5 +++++ 13 files changed, 82 insertions(+), 16 deletions(-) diff --git a/composite.cpp b/composite.cpp index 950ed10a22..c9df4de3ae 100644 --- a/composite.cpp +++ b/composite.cpp @@ -539,7 +539,7 @@ void Compositor::lastFrameRendered() void Compositor::performCompositing() { - if (!isOverlayWindowVisible()) + if (m_scene->usesOverlayWindow() && !isOverlayWindowVisible()) return; // nothing is visible anyway if (!m_scene->isLastFrameRendered()) { m_waitingForFrameRendered = true; @@ -706,7 +706,7 @@ void Compositor::checkUnredirect() // force is needed when the list of windows changes (e.g. a window goes away) void Compositor::checkUnredirect(bool force) { - if (!hasScene() || m_scene->overlayWindow()->window() == None || !options->isUnredirectFullscreen()) + if (!hasScene() || !m_scene->overlayWindow() || m_scene->overlayWindow()->window() == None || !options->isUnredirectFullscreen()) return; if (force) forceUnredirectCheck = true; @@ -716,7 +716,7 @@ void Compositor::checkUnredirect(bool force) void Compositor::delayedCheckUnredirect() { - if (!hasScene() || m_scene->overlayWindow()->window() == None || !(options->isUnredirectFullscreen() || sender() == options)) + if (!hasScene() || !m_scene->overlayWindow() || m_scene->overlayWindow()->window() == None || !(options->isUnredirectFullscreen() || sender() == options)) return; ToplevelList list; bool changed = forceUnredirectCheck; diff --git a/egl_wayland_backend.cpp b/egl_wayland_backend.cpp index 62f5f4d02f..9e436ece77 100644 --- a/egl_wayland_backend.cpp +++ b/egl_wayland_backend.cpp @@ -369,6 +369,11 @@ void EglWaylandBackend::lastFrameRendered() Compositor::self()->lastFrameRendered(); } +bool EglWaylandBackend::usesOverlayWindow() const +{ + return false; +} + /************************************************ * EglTexture ************************************************/ diff --git a/egl_wayland_backend.h b/egl_wayland_backend.h index 8712764ca6..c07d950ca1 100644 --- a/egl_wayland_backend.h +++ b/egl_wayland_backend.h @@ -69,6 +69,7 @@ public: virtual bool isLastFrameRendered() const override; Xcb::Shm *shm(); void lastFrameRendered(); + virtual bool usesOverlayWindow() const override; protected: virtual void present(); diff --git a/eglonxbackend.cpp b/eglonxbackend.cpp index 53442e2a9c..d4205d26a7 100644 --- a/eglonxbackend.cpp +++ b/eglonxbackend.cpp @@ -35,6 +35,7 @@ namespace KWin EglOnXBackend::EglOnXBackend() : OpenGLBackend() + , m_overlayWindow(new OverlayWindow()) , ctx(EGL_NO_CONTEXT) , surfaceHasSubPost(0) , m_bufferAge(0) @@ -46,6 +47,9 @@ EglOnXBackend::EglOnXBackend() EglOnXBackend::~EglOnXBackend() { + if (isFailed()) { + m_overlayWindow->destroy(); + } cleanupGL(); doneCurrent(); eglDestroyContext(dpy, ctx); @@ -55,6 +59,7 @@ EglOnXBackend::~EglOnXBackend() if (overlayWindow()->window()) { overlayWindow()->destroy(); } + delete m_overlayWindow; } static bool gs_tripleBufferUndetected = true; @@ -420,6 +425,16 @@ void EglOnXBackend::doneCurrent() eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); } +bool EglOnXBackend::usesOverlayWindow() const +{ + return true; +} + +OverlayWindow* EglOnXBackend::overlayWindow() +{ + return m_overlayWindow; +} + /************************************************ * EglTexture ************************************************/ diff --git a/eglonxbackend.h b/eglonxbackend.h index 36d47005f6..6c85b1691f 100644 --- a/eglonxbackend.h +++ b/eglonxbackend.h @@ -38,6 +38,8 @@ public: virtual void endRenderingFrame(const QRegion &damage, const QRegion &damagedRegion); virtual bool makeCurrent() override; virtual void doneCurrent() override; + virtual OverlayWindow* overlayWindow() override; + virtual bool usesOverlayWindow() const override; protected: virtual void present(); @@ -46,6 +48,10 @@ private: void init(); bool initBufferConfigs(); bool initRenderingContext(); + /** + * @brief The OverlayWindow used by this Backend. + **/ + OverlayWindow *m_overlayWindow; EGLDisplay dpy; EGLConfig config; EGLSurface surface; diff --git a/glxbackend.cpp b/glxbackend.cpp index 73e9dfa186..e9cd430fc6 100644 --- a/glxbackend.cpp +++ b/glxbackend.cpp @@ -42,6 +42,7 @@ namespace KWin { GlxBackend::GlxBackend() : OpenGLBackend() + , m_overlayWindow(new OverlayWindow()) , window(None) , fbconfig(NULL) , glxWindow(None) @@ -54,6 +55,9 @@ GlxBackend::GlxBackend() GlxBackend::~GlxBackend() { + if (isFailed()) { + m_overlayWindow->destroy(); + } // TODO: cleanup in error case // do cleanup after initBuffer() cleanupGL(); @@ -70,6 +74,7 @@ GlxBackend::~GlxBackend() overlayWindow()->destroy(); checkGLError("Cleanup"); + delete m_overlayWindow; } static bool gs_tripleBufferUndetected = true; @@ -593,6 +598,16 @@ void GlxBackend::doneCurrent() glXMakeCurrent(display(), None, nullptr); } +OverlayWindow* GlxBackend::overlayWindow() +{ + return m_overlayWindow; +} + +bool GlxBackend::usesOverlayWindow() const +{ + return true; +} + /******************************************************** * GlxTexture *******************************************************/ diff --git a/glxbackend.h b/glxbackend.h index 26ca19c27c..d9f81ec426 100644 --- a/glxbackend.h +++ b/glxbackend.h @@ -48,6 +48,8 @@ public: virtual void endRenderingFrame(const QRegion &damage, const QRegion &damagedRegion); virtual bool makeCurrent() override; virtual void doneCurrent() override; + virtual OverlayWindow* overlayWindow() override; + virtual bool usesOverlayWindow() const override; protected: virtual void present(); @@ -61,6 +63,10 @@ private: bool initFbConfig(); void setSwapInterval(int interval); + /** + * @brief The OverlayWindow used by this Backend. + **/ + OverlayWindow *m_overlayWindow; Window window; FBConfigInfo fbcdrawableinfo[ 32 + 1 ]; GLXFBConfig fbconfig; diff --git a/scene.cpp b/scene.cpp index 333514de4a..d13e84b862 100644 --- a/scene.cpp +++ b/scene.cpp @@ -619,6 +619,9 @@ bool Scene::syncsToVBlank() const void Scene::screenGeometryChanged(const QSize &size) { + if (!overlayWindow()) { + return; + } overlayWindow()->resize(size); } diff --git a/scene.h b/scene.h index 1a0855f35d..09689c2da7 100644 --- a/scene.h +++ b/scene.h @@ -121,6 +121,10 @@ public: virtual bool makeOpenGLContextCurrent(); virtual void doneOpenGLContextCurrent(); + /** + * Whether the Scene uses an X11 overlay window to perform compositing. + */ + virtual bool usesOverlayWindow() const = 0; /** * @brief Allows the Compositor to delay the rendering of the next frame until the last one * has been rendered. This is mostly interesting in case that the system compositor is not able diff --git a/scene_opengl.cpp b/scene_opengl.cpp index 6e113ef473..09079cd921 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -79,8 +79,7 @@ extern int currentRefreshRate(); // SceneOpenGL //**************************************** OpenGLBackend::OpenGLBackend() - : m_overlayWindow(new OverlayWindow()) // TODO: maybe create only if needed? - , m_syncsToVBlank(false) + : m_syncsToVBlank(false) , m_blocksForRetrace(false) , m_directRendering(false) , m_haveBufferAge(false) @@ -90,10 +89,6 @@ OpenGLBackend::OpenGLBackend() OpenGLBackend::~OpenGLBackend() { - if (isFailed()) { - m_overlayWindow->destroy(); - } - delete m_overlayWindow; } void OpenGLBackend::setFailed(const QString &reason) @@ -138,6 +133,11 @@ bool OpenGLBackend::isLastFrameRendered() const return true; } +OverlayWindow* OpenGLBackend::overlayWindow() +{ + return NULL; +} + /************************************************ * SceneOpenGL ***********************************************/ diff --git a/scene_opengl.h b/scene_opengl.h index 6d6a0ecc27..6b0fe600c9 100644 --- a/scene_opengl.h +++ b/scene_opengl.h @@ -52,6 +52,7 @@ public: virtual Shadow *createShadow(Toplevel *toplevel); virtual void screenGeometryChanged(const QSize &size); virtual OverlayWindow *overlayWindow(); + virtual bool usesOverlayWindow() const; virtual bool blocksForRetrace() const; virtual bool syncsToVBlank() const; virtual bool makeOpenGLContextCurrent() override; @@ -483,6 +484,7 @@ public: * frame got rendered. If a backend needs more control it needs to implement this method. */ virtual bool isLastFrameRendered() const; + virtual bool usesOverlayWindow() const = 0; /** * @brief Compositor is going into idle mode, flushes any pending paints. **/ @@ -504,9 +506,7 @@ public: * * @return :OverlayWindow* **/ - OverlayWindow *overlayWindow() { - return m_overlayWindow; - } + virtual OverlayWindow *overlayWindow(); /** * @brief Whether the creation of the Backend failed. * @@ -635,10 +635,6 @@ protected: SwapProfiler m_swapProfiler; private: - /** - * @brief The OverlayWindow used by this Backend. - **/ - OverlayWindow *m_overlayWindow; /** * @brief Whether VSync is available and used, defaults to @c false. **/ @@ -683,6 +679,11 @@ inline bool SceneOpenGL::isLastFrameRendered() const return m_backend->isLastFrameRendered(); } +inline bool SceneOpenGL::usesOverlayWindow() const +{ + return m_backend->usesOverlayWindow(); +} + inline SceneOpenGL::Texture* OpenGLWindowPixmap::texture() const { return m_texture.data(); diff --git a/scene_xrender.cpp b/scene_xrender.cpp index ecc0e6d583..6e3525b8db 100644 --- a/scene_xrender.cpp +++ b/scene_xrender.cpp @@ -243,6 +243,11 @@ void X11XRenderBackend::screenGeometryChanged(const QSize &size) init(false); } +bool X11XRenderBackend::usesOverlayWindow() const +{ + return true; +} + //**************************************** // SceneXrender //**************************************** diff --git a/scene_xrender.h b/scene_xrender.h index 59fdb550ab..d9e82a98f4 100644 --- a/scene_xrender.h +++ b/scene_xrender.h @@ -53,6 +53,7 @@ public: * @return :OverlayWindow* **/ virtual OverlayWindow *overlayWindow(); + virtual bool usesOverlayWindow() const = 0; /** * @brief Shows the Overlay Window * @@ -136,6 +137,7 @@ public: virtual OverlayWindow* overlayWindow(); virtual void showOverlay(); virtual void screenGeometryChanged(const QSize &size); + virtual bool usesOverlayWindow() const; private: void init(bool createOverlay); void createBuffer(); @@ -163,6 +165,9 @@ public: virtual OverlayWindow *overlayWindow() { return m_backend->overlayWindow(); } + virtual bool usesOverlayWindow() const { + return m_backend->usesOverlayWindow(); + } virtual bool isLastFrameRendered() const { return m_backend->isLastFrameRendered(); }