[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kwin] /: Move SceneOpenGL into a dedicated plugin
From:       Martin_Flöser <null () kde ! org>
Date:       2017-09-30 11:24:07
Message-ID: E1dyFsN-0004Qd-SQ () code ! kde ! org
[Download RAW message or body]

Git commit 8ae37c420bd3cffae2ae86f91ae5b3f214d7af8b by Martin Flöser.
Committed on 30/09/2017 at 11:12.
Pushed by graesslin into branch 'master'.

Move SceneOpenGL into a dedicated plugin

Summary:
Unfortunately a rather large change which required more refactoring than
initially expected. The main problem was that some parts needed to go
into platformsupport so that the platform plugins can link them. Due to
the rather monolithic nature of scene_opengl.h a few changes were
required:
* SceneOpenGL::Texture -> SceneOpenGLTexture
* SceneOpenGL::TexturePrivate -> SceneOpenGLTexturePrivate
* texture based code into dedicated files
* SwapProfiler code into dedicated files
* SwapProfiler only used in x11 variants
* Safety checks for OpenGL scene moved into the new plugin
* signal declared in SceneOpenGL moved to Scene, so that we don't need
to include SceneOpenGL in composite

Test Plan: Nested OpenGL compositor works

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D7740

M  +0    -2    CMakeLists.txt
M  +3    -42   composite.cpp
M  +1    -0    data/org_kde_kwin.categories
M  +2    -1    lanczosfilter.h
M  +2    -0    libkwineffects/kwingltexture_p.h
M  +1    -0    platformsupport/scenes/CMakeLists.txt
A  +23   -0    platformsupport/scenes/opengl/CMakeLists.txt
R  +16   -12   platformsupport/scenes/opengl/abstract_egl_backend.cpp [from: \
abstract_egl_backend.cpp - 094% similarity] R  +15   -5    \
platformsupport/scenes/opengl/abstract_egl_backend.h [from: abstract_egl_backend.h - \
089% similarity] A  +119  -0    platformsupport/scenes/opengl/backend.cpp     \
[License: GPL (v2)] A  +325  -0    platformsupport/scenes/opengl/backend.h     \
[License: GPL (v2)] A  +57   -0    platformsupport/scenes/opengl/swap_profiler.cpp    \
[License: GPL (v2)] A  +53   -0    platformsupport/scenes/opengl/swap_profiler.h     \
[License: GPL (v2)] A  +80   -0    platformsupport/scenes/opengl/texture.cpp     \
[License: GPL (v2)] A  +76   -0    platformsupport/scenes/opengl/texture.h     \
[License: GPL (v2)] M  +3    -1    plugins/platforms/drm/CMakeLists.txt
M  +2    -2    plugins/platforms/drm/egl_gbm_backend.cpp
M  +2    -3    plugins/platforms/drm/egl_gbm_backend.h
M  +2    -0    plugins/platforms/hwcomposer/CMakeLists.txt
M  +2    -2    plugins/platforms/hwcomposer/egl_hwcomposer_backend.cpp
M  +2    -2    plugins/platforms/hwcomposer/egl_hwcomposer_backend.h
M  +2    -1    plugins/platforms/virtual/CMakeLists.txt
M  +3    -2    plugins/platforms/virtual/egl_gbm_backend.cpp
M  +2    -3    plugins/platforms/virtual/egl_gbm_backend.h
M  +1    -0    plugins/platforms/virtual/virtual_backend.cpp
M  +2    -1    plugins/platforms/wayland/CMakeLists.txt
M  +2    -2    plugins/platforms/wayland/egl_wayland_backend.cpp
M  +2    -3    plugins/platforms/wayland/egl_wayland_backend.h
M  +1    -0    plugins/platforms/x11/common/CMakeLists.txt
M  +6    -2    plugins/platforms/x11/common/eglonxbackend.cpp
M  +6    -3    plugins/platforms/x11/common/eglonxbackend.h
M  +3    -1    plugins/platforms/x11/standalone/CMakeLists.txt
M  +8    -4    plugins/platforms/x11/standalone/glxbackend.cpp
M  +9    -5    plugins/platforms/x11/standalone/glxbackend.h
M  +2    -1    plugins/platforms/x11/windowed/CMakeLists.txt
M  +2    -0    plugins/platforms/x11/windowed/x11windowed_backend.cpp
M  +1    -0    plugins/scenes/CMakeLists.txt
A  +26   -0    plugins/scenes/opengl/CMakeLists.txt
A  +9    -0    plugins/scenes/opengl/opengl.json
R  +58   -210  plugins/scenes/opengl/scene_opengl.cpp [from: scene_opengl.cpp - 092% \
similarity] A  +354  -0    plugins/scenes/opengl/scene_opengl.h     [License: GPL \
(v2)] M  +1    -0    scene.h
D  +0    -694  scene_opengl.h

https://commits.kde.org/kwin/8ae37c420bd3cffae2ae86f91ae5b3f214d7af8b

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2e7c80257..7e9b5e0c8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -423,7 +423,6 @@ set(kwin_KDEINIT_SRCS
    toplevel.cpp
    unmanaged.cpp
    scene.cpp
-   scene_opengl.cpp
    screenlockerwatcher.cpp
    thumbnailitem.cpp
    lanczosfilter.cpp
@@ -453,7 +452,6 @@ set(kwin_KDEINIT_SRCS
     decorations/settings.cpp
     decorations/decorationrenderer.cpp
     decorations/decorations_logging.cpp
-    abstract_egl_backend.cpp
     platform.cpp
     shell_client.cpp
     wayland_server.cpp
diff --git a/composite.cpp b/composite.cpp
index ca984004a..7ffb1fdf0 100644
--- a/composite.cpp
+++ b/composite.cpp
@@ -29,7 +29,6 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #include "effects.h"
 #include "overlaywindow.h"
 #include "scene.h"
-#include "scene_opengl.h"
 #include "screens.h"
 #include "shadow.h"
 #include "useractions.h"
@@ -39,6 +38,8 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #include "wayland_server.h"
 #include "decorations/decoratedclient.h"
 
+#include <kwingltexture.h>
+
 #include <KWayland/Server/surface_interface.h>
 
 #include <stdio.h>
@@ -220,47 +221,6 @@ void Compositor::slotCompositingOptionsInitialized()
         }
     }
 
-    if (!m_scene) {
-        switch(options->compositingMode()) {
-        case OpenGLCompositing: {
-            qCDebug(KWIN_CORE) << "Initializing OpenGL compositing";
-
-            // Some broken drivers crash on glXQuery() so to prevent constant KWin \
                crashes:
-            if (kwinApp()->platform()->openGLCompositingIsBroken())
-                qCWarning(KWIN_CORE) << "KWin has detected that your OpenGL library \
                is unsafe to use";
-            else {
-                kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PreInit);
                
-
-                m_scene = SceneOpenGL::createScene(this);
-
-                kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PostInit);
                
-
-                if (m_scene && !m_scene->initFailed()) {
-                    connect(static_cast<SceneOpenGL*>(m_scene), \
                &SceneOpenGL::resetCompositing, this, &Compositor::restart);
-                    break; // -->
-                }
-                delete m_scene;
-                m_scene = NULL;
-            }
-
-            // Do not Fall back to XRender - it causes problems when selfcheck fails \
                during startup, but works later on
-            break;
-        }
-        default:
-            qCDebug(KWIN_CORE) << "No compositing enabled";
-            m_starting = false;
-            if (cm_selection) {
-                cm_selection->owning = false;
-                cm_selection->release();
-            }
-            if (kwinApp()->platform()->requiresCompositing()) {
-                qCCritical(KWIN_CORE) << "The used windowing system requires \
                compositing";
-                qCCritical(KWIN_CORE) << "We are going to quit KWin now as it is \
                broken";
-                qApp->quit();
-            }
-            return;
-        }
-    }
     if (m_scene == NULL || m_scene->initFailed()) {
         qCCritical(KWIN_CORE) << "Failed to initialize compositing, compositing \
disabled";  delete m_scene;
@@ -277,6 +237,7 @@ void Compositor::slotCompositingOptionsInitialized()
         }
         return;
     }
+    connect(m_scene, &Scene::resetCompositing, this, &Compositor::restart);
     emit sceneCreated();
 
     if (Workspace::self()) {
diff --git a/data/org_kde_kwin.categories b/data/org_kde_kwin.categories
index e73674fc1..a256fa2c5 100644
--- a/data/org_kde_kwin.categories
+++ b/data/org_kde_kwin.categories
@@ -18,3 +18,4 @@ kwin_xkbcommon KWin xkbcommon integration
 kwin_qpa_plugin KWin QtPlatformAbstraction plugin
 kwin_scene_xrender KWin XRender based compositor scene plugin
 kwin_scene_qpainter KWin QPainter based compositor scene plugin
+kwin_scene_opengl KWin OpenGL based compositor scene plugins
diff --git a/lanczosfilter.h b/lanczosfilter.h
index fff5cf28e..90dff420c 100644
--- a/lanczosfilter.h
+++ b/lanczosfilter.h
@@ -29,6 +29,7 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #include <QVector4D>
 
 #include <kwinconfig.h>
+#include <kwin_export.h>
 
 namespace KWin
 {
@@ -40,7 +41,7 @@ class GLTexture;
 class GLRenderTarget;
 class GLShader;
 
-class LanczosFilter
+class KWIN_EXPORT LanczosFilter
     : public QObject
 {
     Q_OBJECT
diff --git a/libkwineffects/kwingltexture_p.h b/libkwineffects/kwingltexture_p.h
index 440d2ce94..cec4c6c1f 100644
--- a/libkwineffects/kwingltexture_p.h
+++ b/libkwineffects/kwingltexture_p.h
@@ -29,6 +29,8 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #include <QSize>
 #include <QSharedData>
 #include <QImage>
+#include <QMatrix4x4>
+#include <epoxy/gl.h>
 
 namespace KWin
 {
diff --git a/platformsupport/scenes/CMakeLists.txt \
b/platformsupport/scenes/CMakeLists.txt index 2e1df3548..6e560cbcd 100644
--- a/platformsupport/scenes/CMakeLists.txt
+++ b/platformsupport/scenes/CMakeLists.txt
@@ -1 +1,2 @@
 add_subdirectory(qpainter)
+add_subdirectory(opengl)
diff --git a/platformsupport/scenes/opengl/CMakeLists.txt \
b/platformsupport/scenes/opengl/CMakeLists.txt new file mode 100644
index 000000000..26123568d
--- /dev/null
+++ b/platformsupport/scenes/opengl/CMakeLists.txt
@@ -0,0 +1,23 @@
+set(SCENE_OPENGL_BACKEND_SRCS
+    abstract_egl_backend.cpp
+    backend.cpp
+    swap_profiler.cpp
+    texture.cpp
+)
+
+include_directories(${CMAKE_SOURCE_DIR})
+
+include(ECMQtDeclareLoggingCategory)
+ecm_qt_declare_logging_category(SCENE_OPENGL_BACKEND_SRCS
+    HEADER
+        logging.h
+    IDENTIFIER
+        KWIN_OPENGL
+    CATEGORY_NAME
+        kwin_scene_opengl
+    DEFAULT_SEVERITY
+        Critical
+)
+
+add_library(SceneOpenGLBackend STATIC ${SCENE_OPENGL_BACKEND_SRCS})
+target_link_libraries(SceneOpenGLBackend Qt5::Core Qt5::Widgets KF5::CoreAddons \
                KF5::ConfigCore KF5::WindowSystem)
diff --git a/abstract_egl_backend.cpp \
b/platformsupport/scenes/opengl/abstract_egl_backend.cpp similarity index 94%
rename from abstract_egl_backend.cpp
rename to platformsupport/scenes/opengl/abstract_egl_backend.cpp
index 209d37261..91729b480 100644
--- a/abstract_egl_backend.cpp
+++ b/platformsupport/scenes/opengl/abstract_egl_backend.cpp
@@ -18,16 +18,20 @@ You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *********************************************************************/
 #include "abstract_egl_backend.h"
+#include "texture.h"
 #include "composite.h"
 #include "egl_context_attribute_builder.h"
 #include "options.h"
 #include "platform.h"
+#include "scene.h"
 #include "wayland_server.h"
 #include <KWayland/Server/buffer_interface.h>
 #include <KWayland/Server/display.h>
 #include <KWayland/Server/surface_interface.h>
 // kwin libs
+#include <logging.h>
 #include <kwinglplatform.h>
+#include <kwinglutils.h>
 // Qt
 #include <QOpenGLContext>
 #include <QOpenGLFramebufferObject>
@@ -93,25 +97,25 @@ bool AbstractEglBackend::initEglAPI()
 {
     EGLint major, minor;
     if (eglInitialize(m_display, &major, &minor) == EGL_FALSE) {
-        qCWarning(KWIN_CORE) << "eglInitialize failed";
+        qCWarning(KWIN_OPENGL) << "eglInitialize failed";
         EGLint error = eglGetError();
         if (error != EGL_SUCCESS) {
-            qCWarning(KWIN_CORE) << "Error during eglInitialize " << error;
+            qCWarning(KWIN_OPENGL) << "Error during eglInitialize " << error;
         }
         return false;
     }
     EGLint error = eglGetError();
     if (error != EGL_SUCCESS) {
-        qCWarning(KWIN_CORE) << "Error during eglInitialize " << error;
+        qCWarning(KWIN_OPENGL) << "Error during eglInitialize " << error;
         return false;
     }
-    qCDebug(KWIN_CORE) << "Egl Initialize succeeded";
+    qCDebug(KWIN_OPENGL) << "Egl Initialize succeeded";
 
     if (eglBindAPI(isOpenGLES() ? EGL_OPENGL_ES_API : EGL_OPENGL_API) == EGL_FALSE) \
                {
-        qCCritical(KWIN_CORE) << "bind OpenGL API failed";
+        qCCritical(KWIN_OPENGL) << "bind OpenGL API failed";
         return false;
     }
-    qCDebug(KWIN_CORE) << "EGL version: " << major << "." << minor;
+    qCDebug(KWIN_OPENGL) << "EGL version: " << major << "." << minor;
     const QByteArray eglExtensions = eglQueryString(m_display, EGL_EXTENSIONS);
     setExtensions(eglExtensions.split(' '));
     return true;
@@ -250,13 +254,13 @@ bool AbstractEglBackend::createContext()
         const auto attribs = (*it)->build();
         ctx = eglCreateContext(m_display, config(), EGL_NO_CONTEXT, attribs.data());
         if (ctx != EGL_NO_CONTEXT) {
-            qCDebug(KWIN_CORE) << "Created EGL context with attributes:" << \
(*it).get(); +            qCDebug(KWIN_OPENGL) << "Created EGL context with \
attributes:" << (*it).get();  break;
         }
     }
 
     if (ctx == EGL_NO_CONTEXT) {
-        qCCritical(KWIN_CORE) << "Create Context failed";
+        qCCritical(KWIN_OPENGL) << "Create Context failed";
         return false;
     }
     m_context = ctx;
@@ -281,8 +285,8 @@ void AbstractEglBackend::setSurface(const EGLSurface &surface)
     kwinApp()->platform()->setSceneEglSurface(surface);
 }
 
-AbstractEglTexture::AbstractEglTexture(SceneOpenGL::Texture *texture, \
                AbstractEglBackend *backend)
-    : SceneOpenGL::TexturePrivate()
+AbstractEglTexture::AbstractEglTexture(SceneOpenGLTexture *texture, \
AbstractEglBackend *backend) +    : SceneOpenGLTexturePrivate()
     , q(texture)
     , m_backend(backend)
     , m_image(EGL_NO_IMAGE_KHR)
@@ -453,7 +457,7 @@ bool AbstractEglTexture::loadEglTexture(const QPointer< \
KWayland::Server::Buffer  q->unbind();
 
     if (EGL_NO_IMAGE_KHR == m_image) {
-        qCDebug(KWIN_CORE) << "failed to create egl image";
+        qCDebug(KWIN_OPENGL) << "failed to create egl image";
         q->discard();
         return false;
     }
@@ -466,7 +470,7 @@ EGLImageKHR AbstractEglTexture::attach(const QPointer< \
KWayland::Server::BufferI  EGLint format, yInverted;
     eglQueryWaylandBufferWL(m_backend->eglDisplay(), buffer->resource(), \
EGL_TEXTURE_FORMAT, &format);  if (format != EGL_TEXTURE_RGB && format != \
                EGL_TEXTURE_RGBA) {
-        qCDebug(KWIN_CORE) << "Unsupported texture format: " << format;
+        qCDebug(KWIN_OPENGL) << "Unsupported texture format: " << format;
         return EGL_NO_IMAGE_KHR;
     }
     if (!eglQueryWaylandBufferWL(m_backend->eglDisplay(), buffer->resource(), \
                EGL_WAYLAND_Y_INVERTED_WL, &yInverted)) {
diff --git a/abstract_egl_backend.h \
b/platformsupport/scenes/opengl/abstract_egl_backend.h similarity index 89%
rename from abstract_egl_backend.h
rename to platformsupport/scenes/opengl/abstract_egl_backend.h
index 35b4f3bb9..50d1a8282 100644
--- a/abstract_egl_backend.h
+++ b/platformsupport/scenes/opengl/abstract_egl_backend.h
@@ -19,13 +19,23 @@ along with this program.  If not, see \
                <http://www.gnu.org/licenses/>.
 *********************************************************************/
 #ifndef KWIN_ABSTRACT_EGL_BACKEND_H
 #define KWIN_ABSTRACT_EGL_BACKEND_H
-#include "scene_opengl.h"
+#include "backend.h"
+#include "texture.h"
 
+#include <QObject>
 #include <epoxy/egl.h>
 #include <fixx11h.h>
 
 class QOpenGLFramebufferObject;
 
+namespace KWayland
+{
+namespace Server
+{
+class BufferInterface;
+}
+}
+
 namespace KWin
 {
 
@@ -77,7 +87,7 @@ private:
     QList<QByteArray> m_clientExtensions;
 };
 
-class KWIN_EXPORT AbstractEglTexture : public SceneOpenGL::TexturePrivate
+class KWIN_EXPORT AbstractEglTexture : public SceneOpenGLTexturePrivate
 {
 public:
     virtual ~AbstractEglTexture();
@@ -86,14 +96,14 @@ public:
     OpenGLBackend *backend() override;
 
 protected:
-    AbstractEglTexture(SceneOpenGL::Texture *texture, AbstractEglBackend *backend);
+    AbstractEglTexture(SceneOpenGLTexture *texture, AbstractEglBackend *backend);
     EGLImageKHR image() const {
         return m_image;
     }
     void setImage(const EGLImageKHR &img) {
         m_image = img;
     }
-    SceneOpenGL::Texture *texture() const {
+    SceneOpenGLTexture *texture() const {
         return q;
     }
 
@@ -102,7 +112,7 @@ private:
     bool loadEglTexture(const QPointer<KWayland::Server::BufferInterface> &buffer);
     EGLImageKHR attach(const QPointer<KWayland::Server::BufferInterface> &buffer);
     bool updateFromFBO(const QSharedPointer<QOpenGLFramebufferObject> &fbo);
-    SceneOpenGL::Texture *q;
+    SceneOpenGLTexture *q;
     AbstractEglBackend *m_backend;
     EGLImageKHR m_image;
 };
diff --git a/platformsupport/scenes/opengl/backend.cpp \
b/platformsupport/scenes/opengl/backend.cpp new file mode 100644
index 000000000..cb0a23d53
--- /dev/null
+++ b/platformsupport/scenes/opengl/backend.cpp
@@ -0,0 +1,119 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
+Copyright (C) 2009, 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
+
+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 <http://www.gnu.org/licenses/>.
+*********************************************************************/
+#include "backend.h"
+#include <kwineffects.h>
+#include <logging.h>
+
+#include "screens.h"
+
+#include <epoxy/gl.h>
+
+namespace KWin
+{
+
+OpenGLBackend::OpenGLBackend()
+    : m_syncsToVBlank(false)
+    , m_blocksForRetrace(false)
+    , m_directRendering(false)
+    , m_haveBufferAge(false)
+    , m_failed(false)
+{
+}
+
+OpenGLBackend::~OpenGLBackend()
+{
+}
+
+void OpenGLBackend::setFailed(const QString &reason)
+{
+    qCWarning(KWIN_OPENGL) << "Creating the OpenGL rendering failed: " << reason;
+    m_failed = true;
+}
+
+void OpenGLBackend::idle()
+{
+    if (hasPendingFlush()) {
+        effects->makeOpenGLContextCurrent();
+        present();
+    }
+}
+
+void OpenGLBackend::addToDamageHistory(const QRegion &region)
+{
+    if (m_damageHistory.count() > 10)
+        m_damageHistory.removeLast();
+
+    m_damageHistory.prepend(region);
+}
+
+QRegion OpenGLBackend::accumulatedDamageHistory(int bufferAge) const
+{
+    QRegion region;
+
+    // Note: An age of zero means the buffer contents are undefined
+    if (bufferAge > 0 && bufferAge <= m_damageHistory.count()) {
+        for (int i = 0; i < bufferAge - 1; i++)
+            region |= m_damageHistory[i];
+    } else {
+        const QSize &s = screens()->size();
+        region = QRegion(0, 0, s.width(), s.height());
+    }
+
+    return region;
+}
+
+OverlayWindow* OpenGLBackend::overlayWindow()
+{
+    return NULL;
+}
+
+QRegion OpenGLBackend::prepareRenderingForScreen(int screenId)
+{
+    // fallback to repaint complete screen
+    return screens()->geometry(screenId);
+}
+
+void OpenGLBackend::endRenderingFrameForScreen(int screenId, const QRegion &damage, \
const QRegion &damagedRegion) +{
+    Q_UNUSED(screenId)
+    Q_UNUSED(damage)
+    Q_UNUSED(damagedRegion)
+}
+
+bool OpenGLBackend::perScreenRendering() const
+{
+    return false;
+}
+
+void OpenGLBackend::copyPixels(const QRegion &region)
+{
+    const int height = screens()->size().height();
+    foreach (const QRect &r, region.rects()) {
+        const int x0 = r.x();
+        const int y0 = height - r.y() - r.height();
+        const int x1 = r.x() + r.width();
+        const int y1 = height - r.y();
+
+        glBlitFramebuffer(x0, y0, x1, y1, x0, y0, x1, y1, GL_COLOR_BUFFER_BIT, \
GL_NEAREST); +    }
+}
+
+}
diff --git a/platformsupport/scenes/opengl/backend.h \
b/platformsupport/scenes/opengl/backend.h new file mode 100644
index 000000000..483c71186
--- /dev/null
+++ b/platformsupport/scenes/opengl/backend.h
@@ -0,0 +1,325 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
+Copyright (C) 2009, 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
+
+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 <http://www.gnu.org/licenses/>.
+*********************************************************************/
+#ifndef KWIN_SCENE_OPENGL_BACKEND_H
+#define KWIN_SCENE_OPENGL_BACKEND_H
+
+#include <QElapsedTimer>
+#include <QRegion>
+
+#include <kwin_export.h>
+
+namespace KWin
+{
+class OpenGLBackend;
+class OverlayWindow;
+class SceneOpenGL;
+class SceneOpenGLTexture;
+class SceneOpenGLTexturePrivate;
+class WindowPixmap;
+
+/**
+ * @brief The OpenGLBackend creates and holds the OpenGL context and is responsible \
for Texture from Pixmap. + *
+ * The OpenGLBackend is an abstract base class used by the SceneOpenGL to abstract \
away the differences + * between various OpenGL windowing systems such as GLX and \
EGL. + *
+ * A concrete implementation has to create and release the OpenGL context in a way \
so that the + * SceneOpenGL does not have to care about it.
+ *
+ * In addition a major task for this class is to generate the \
SceneOpenGLTexturePrivate which is + * able to perform the texture from pixmap \
operation in the given backend. + *
+ * @author Martin Gräßlin <mgraesslin@kde.org>
+ **/
+class KWIN_EXPORT OpenGLBackend
+{
+public:
+    OpenGLBackend();
+    virtual ~OpenGLBackend();
+
+    virtual void init() = 0;
+    /**
+     * @return Time passes since start of rendering current frame.
+     * @see startRenderTimer
+     **/
+    qint64 renderTime() {
+        return m_renderTimer.nsecsElapsed();
+    }
+    virtual void screenGeometryChanged(const QSize &size) = 0;
+    virtual SceneOpenGLTexturePrivate *createBackendTexture(SceneOpenGLTexture \
*texture) = 0; +
+    /**
+     * @brief Backend specific code to prepare the rendering of a frame including \
flushing the +     * previously rendered frame to the screen if the backend works \
this way. +     *
+     * @return A region that if not empty will be repainted in addition to the \
damaged region +     **/
+    virtual QRegion prepareRenderingFrame() = 0;
+
+    /**
+     * @brief Backend specific code to handle the end of rendering a frame.
+     *
+     * @param renderedRegion The possibly larger region that has been rendered
+     * @param damagedRegion The damaged region that should be posted
+     **/
+    virtual void endRenderingFrame(const QRegion &damage, const QRegion \
&damagedRegion) = 0; +    virtual void endRenderingFrameForScreen(int screenId, const \
QRegion &damage, const QRegion &damagedRegion); +    virtual bool makeCurrent() = 0;
+    virtual void doneCurrent() = 0;
+    virtual bool usesOverlayWindow() const = 0;
+    /**
+     * Whether the rendering needs to be split per screen.
+     * Default implementation returns @c false.
+     **/
+    virtual bool perScreenRendering() const;
+    virtual QRegion prepareRenderingForScreen(int screenId);
+    /**
+     * @brief Compositor is going into idle mode, flushes any pending paints.
+     **/
+    void idle();
+
+    /**
+     * @return bool Whether the scene needs to flush a frame.
+     **/
+    bool hasPendingFlush() const {
+        return !m_lastDamage.isEmpty();
+    }
+
+    /**
+     * @brief Returns the OverlayWindow used by the backend.
+     *
+     * A backend does not have to use an OverlayWindow, this is mostly for the X \
world. +     * In case the backend does not use an OverlayWindow it is allowed to \
return @c null. +     * It's the task of the caller to check whether it is @c null.
+     *
+     * @return :OverlayWindow*
+     **/
+    virtual OverlayWindow *overlayWindow();
+    /**
+     * @brief Whether the creation of the Backend failed.
+     *
+     * The SceneOpenGL should test whether the Backend got constructed correctly. If \
this method +     * returns @c true, the SceneOpenGL should not try to start the \
rendering. +     *
+     * @return bool @c true if the creation of the Backend failed, @c false \
otherwise. +     **/
+    bool isFailed() const {
+        return m_failed;
+    }
+    /**
+     * @brief Whether the Backend provides VSync.
+     *
+     * Currently only the GLX backend can provide VSync.
+     *
+     * @return bool @c true if VSync support is available, @c false otherwise
+     **/
+    bool syncsToVBlank() const {
+        return m_syncsToVBlank;
+    }
+    /**
+     * @brief Whether VSync blocks execution until the screen is in the retrace
+     *
+     * Case for waitVideoSync and non triple buffering buffer swaps
+     *
+     **/
+    bool blocksForRetrace() const {
+        return m_blocksForRetrace;
+    }
+    /**
+     * @brief Whether the backend uses direct rendering.
+     *
+     * Some OpenGLScene modes require direct rendering. E.g. the OpenGL 2 should not \
be used +     * if direct rendering is not supported by the Scene.
+     *
+     * @return bool @c true if the GL context is direct, @c false if indirect
+     **/
+    bool isDirectRendering() const {
+        return m_directRendering;
+    }
+
+    bool supportsBufferAge() const {
+        return m_haveBufferAge;
+    }
+
+    /**
+     * @returns whether the context is surfaceless
+     **/
+    bool isSurfaceLessContext() const {
+        return m_surfaceLessContext;
+    }
+
+    /**
+     * Returns the damage that has accumulated since a buffer of the given age was \
presented. +     */
+    QRegion accumulatedDamageHistory(int bufferAge) const;
+
+    /**
+     * Saves the given region to damage history.
+     */
+    void addToDamageHistory(const QRegion &region);
+
+    /**
+     * The backend specific extensions (e.g. EGL/GLX extensions).
+     *
+     * Not the OpenGL (ES) extension!
+     **/
+    QList<QByteArray> extensions() const {
+        return m_extensions;
+    }
+
+    /**
+     * @returns whether the backend specific extensions contains @p extension.
+     **/
+    bool hasExtension(const QByteArray &extension) const {
+        return m_extensions.contains(extension);
+    }
+
+    /**
+     * Copy a region of pixels from the current read to the current draw buffer
+     */
+    void copyPixels(const QRegion &region);
+
+protected:
+    /**
+     * @brief Backend specific flushing of frame to screen.
+     **/
+    virtual void present() = 0;
+    /**
+     * @brief Sets the backend initialization to failed.
+     *
+     * This method should be called by the concrete subclass in case the \
initialization failed. +     * The given @p reason is logged as a warning.
+     *
+     * @param reason The reason why the initialization failed.
+     **/
+    void setFailed(const QString &reason);
+    /**
+     * @brief Sets whether the backend provides VSync.
+     *
+     * Should be called by the concrete subclass once it is determined whether VSync \
is supported. +     * If the subclass does not call this method, the backend defaults \
to @c false. +     * @param enabled @c true if VSync support available, @c false \
otherwise. +     **/
+    void setSyncsToVBlank(bool enabled) {
+        m_syncsToVBlank = enabled;
+    }
+    /**
+     * @brief Sets whether the VSync iplementation blocks
+     *
+     * Should be called by the concrete subclass once it is determined how VSync \
works. +     * If the subclass does not call this method, the backend defaults to @c \
false. +     * @param enabled @c true if VSync blocks, @c false otherwise.
+     **/
+    void setBlocksForRetrace(bool enabled) {
+        m_blocksForRetrace = enabled;
+    }
+    /**
+     * @brief Sets whether the OpenGL context is direct.
+     *
+     * Should be called by the concrete subclass once it is determined whether the \
OpenGL context is +     * direct or indirect.
+     * If the subclass does not call this method, the backend defaults to @c false.
+     *
+     * @param direct @c true if the OpenGL context is direct, @c false if indirect
+     **/
+    void setIsDirectRendering(bool direct) {
+        m_directRendering = direct;
+    }
+
+    void setSupportsBufferAge(bool value) {
+        m_haveBufferAge = value;
+    }
+
+    /**
+     * @return const QRegion& Damage of previously rendered frame
+     **/
+    const QRegion &lastDamage() const {
+        return m_lastDamage;
+    }
+    void setLastDamage(const QRegion &damage) {
+        m_lastDamage = damage;
+    }
+    /**
+     * @brief Starts the timer for how long it takes to render the frame.
+     *
+     * @see renderTime
+     **/
+    void startRenderTimer() {
+        m_renderTimer.start();
+    }
+
+    /**
+     * @param set whether the context is surface less
+     **/
+    void setSurfaceLessContext(bool set) {
+        m_surfaceLessContext = set;
+    }
+
+    /**
+     * Sets the platform-specific @p extensions.
+     *
+     * These are the EGL/GLX extensions, not the OpenGL extensions
+     **/
+    void setExtensions(const QList<QByteArray> &extensions) {
+        m_extensions = extensions;
+    }
+
+private:
+    /**
+     * @brief Whether VSync is available and used, defaults to @c false.
+     **/
+    bool m_syncsToVBlank;
+    /**
+     * @brief Whether present() will block execution until the next vertical retrace \
@c false. +     **/
+    bool m_blocksForRetrace;
+    /**
+     * @brief Whether direct rendering is used, defaults to @c false.
+     **/
+    bool m_directRendering;
+    /**
+     * @brief Whether the backend supports GLX_EXT_buffer_age / EGL_EXT_buffer_age.
+     */
+    bool m_haveBufferAge;
+    /**
+     * @brief Whether the initialization failed, of course default to @c false.
+     **/
+    bool m_failed;
+    /**
+     * @brief Damaged region of previously rendered frame.
+     **/
+    QRegion m_lastDamage;
+    /**
+     * @brief The damage history for the past 10 frames.
+     */
+    QList<QRegion> m_damageHistory;
+    /**
+     * @brief Timer to measure how long a frame renders.
+     **/
+    QElapsedTimer m_renderTimer;
+    bool m_surfaceLessContext = false;
+
+    QList<QByteArray> m_extensions;
+};
+
+}
+
+#endif
diff --git a/platformsupport/scenes/opengl/swap_profiler.cpp \
b/platformsupport/scenes/opengl/swap_profiler.cpp new file mode 100644
index 000000000..619a2ae65
--- /dev/null
+++ b/platformsupport/scenes/opengl/swap_profiler.cpp
@@ -0,0 +1,57 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
+Copyright (C) 2009, 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
+
+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 <http://www.gnu.org/licenses/>.
+*********************************************************************/
+#include "swap_profiler.h"
+#include <logging.h>
+
+namespace KWin
+{
+
+SwapProfiler::SwapProfiler()
+{
+    init();
+}
+
+void SwapProfiler::init()
+{
+    m_time = 2 * 1000*1000; // we start with a long time mean of 2ms ...
+    m_counter = 0;
+}
+
+void SwapProfiler::begin()
+{
+    m_timer.start();
+}
+
+char SwapProfiler::end()
+{
+    // .. and blend in actual values.
+    // this way we prevent extremes from killing our long time mean
+    m_time = (10*m_time + m_timer.nsecsElapsed())/11;
+    if (++m_counter > 500) {
+        const bool blocks = m_time > 1000 * 1000; // 1ms, i get ~250 µs and ~7ms w/o \
triple buffering... +        qCDebug(KWIN_OPENGL) << "Triple buffering detection:" << \
QString(blocks ? QStringLiteral("NOT available") : QStringLiteral("Available")) << +  \
" - Mean block time:" << m_time/(1000.0*1000.0) << "ms"; +        return blocks ? 'd' \
: 't'; +    }
+    return 0;
+}
+
+}
diff --git a/platformsupport/scenes/opengl/swap_profiler.h \
b/platformsupport/scenes/opengl/swap_profiler.h new file mode 100644
index 000000000..8415b0a8d
--- /dev/null
+++ b/platformsupport/scenes/opengl/swap_profiler.h
@@ -0,0 +1,53 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
+Copyright (C) 2009, 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
+
+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 <http://www.gnu.org/licenses/>.
+*********************************************************************/
+#ifndef KWIN_SCENE_OPENGL_SWAP_PROFILER_H
+#define KWIN_SCENE_OPENGL_SWAP_PROFILER_H
+
+#include <QElapsedTimer>
+#include <kwin_export.h>
+
+namespace KWin
+{
+
+/**
+ * @short Profiler to detect whether we have triple buffering
+ * The strategy is to start setBlocksForRetrace(false) but assume blocking and have \
the system prove that assumption wrong + **/
+class KWIN_EXPORT SwapProfiler
+{
+public:
+    SwapProfiler();
+    void init();
+    void begin();
+    /**
+     * @return char being 'd' for double, 't' for triple (or more - but \
non-blocking) buffering and +     * 0 (NOT '0') otherwise, so you can act on "if \
(char result = SwapProfiler::end()) { fooBar(); } +     **/
+    char end();
+private:
+    QElapsedTimer m_timer;
+    qint64  m_time;
+    int m_counter;
+};
+
+}
+
+#endif
diff --git a/platformsupport/scenes/opengl/texture.cpp \
b/platformsupport/scenes/opengl/texture.cpp new file mode 100644
index 000000000..936272002
--- /dev/null
+++ b/platformsupport/scenes/opengl/texture.cpp
@@ -0,0 +1,80 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
+Copyright (C) 2009, 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
+
+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 <http://www.gnu.org/licenses/>.
+*********************************************************************/
+#include "texture.h"
+#include "backend.h"
+#include "scene.h"
+
+namespace KWin
+{
+
+SceneOpenGLTexture::SceneOpenGLTexture(OpenGLBackend *backend)
+    : GLTexture(*backend->createBackendTexture(this))
+{
+}
+
+SceneOpenGLTexture::~SceneOpenGLTexture()
+{
+}
+
+SceneOpenGLTexture& SceneOpenGLTexture::operator = (const SceneOpenGLTexture& tex)
+{
+    d_ptr = tex.d_ptr;
+    return *this;
+}
+
+void SceneOpenGLTexture::discard()
+{
+    d_ptr = d_func()->backend()->createBackendTexture(this);
+}
+
+bool SceneOpenGLTexture::load(WindowPixmap *pixmap)
+{
+    if (!pixmap->isValid()) {
+        return false;
+    }
+
+    // decrease the reference counter for the old texture
+    d_ptr = d_func()->backend()->createBackendTexture(this); //new TexturePrivate();
+
+    Q_D(SceneOpenGLTexture);
+    return d->loadTexture(pixmap);
+}
+
+void SceneOpenGLTexture::updateFromPixmap(WindowPixmap *pixmap)
+{
+    Q_D(SceneOpenGLTexture);
+    d->updateTexture(pixmap);
+}
+
+SceneOpenGLTexturePrivate::SceneOpenGLTexturePrivate()
+{
+}
+
+SceneOpenGLTexturePrivate::~SceneOpenGLTexturePrivate()
+{
+}
+
+void SceneOpenGLTexturePrivate::updateTexture(WindowPixmap *pixmap)
+{
+    Q_UNUSED(pixmap)
+}
+
+}
diff --git a/platformsupport/scenes/opengl/texture.h \
b/platformsupport/scenes/opengl/texture.h new file mode 100644
index 000000000..d574b0cb5
--- /dev/null
+++ b/platformsupport/scenes/opengl/texture.h
@@ -0,0 +1,76 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
+Copyright (C) 2009, 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
+
+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 <http://www.gnu.org/licenses/>.
+*********************************************************************/
+#ifndef KWIN_SCENE_OPENGL_TEXTURE_H
+#define KWIN_SCENE_OPENGL_TEXTURE_H
+
+#include <kwingltexture.h>
+#include <kwingltexture_p.h>
+
+namespace KWin
+{
+
+class OpenGLBackend;
+class WindowPixmap;
+class SceneOpenGLTexturePrivate;
+
+class SceneOpenGLTexture
+    : public GLTexture
+{
+public:
+    SceneOpenGLTexture(OpenGLBackend *backend);
+    virtual ~SceneOpenGLTexture();
+
+    SceneOpenGLTexture & operator = (const SceneOpenGLTexture& tex);
+
+    void discard() override final;
+
+protected:
+    bool load(WindowPixmap *pixmap);
+    void updateFromPixmap(WindowPixmap *pixmap);
+
+    SceneOpenGLTexture(SceneOpenGLTexturePrivate& dd);
+
+private:
+    Q_DECLARE_PRIVATE(SceneOpenGLTexture)
+
+    friend class OpenGLWindowPixmap;
+};
+
+class SceneOpenGLTexturePrivate
+    : public GLTexturePrivate
+{
+public:
+    virtual ~SceneOpenGLTexturePrivate();
+
+    virtual bool loadTexture(WindowPixmap *pixmap) = 0;
+    virtual void updateTexture(WindowPixmap *pixmap);
+    virtual OpenGLBackend *backend() = 0;
+
+protected:
+    SceneOpenGLTexturePrivate();
+
+private:
+    Q_DISABLE_COPY(SceneOpenGLTexturePrivate)
+};
+
+}
+
+#endif
diff --git a/plugins/platforms/drm/CMakeLists.txt \
b/plugins/platforms/drm/CMakeLists.txt index 8db5207a7..f3b7e7c3f 100644
--- a/plugins/platforms/drm/CMakeLists.txt
+++ b/plugins/platforms/drm/CMakeLists.txt
@@ -16,8 +16,10 @@ if(HAVE_GBM)
     set(DRM_SOURCES ${DRM_SOURCES} egl_gbm_backend.cpp drm_buffer_gbm.cpp)
 endif()
 
+include_directories(${CMAKE_SOURCE_DIR}/platformsupport/scenes/opengl)
+
 add_library(KWinWaylandDrmBackend MODULE ${DRM_SOURCES})
-target_link_libraries(KWinWaylandDrmBackend kwin Libdrm::Libdrm \
SceneQPainterBackend) +target_link_libraries(KWinWaylandDrmBackend kwin \
Libdrm::Libdrm SceneQPainterBackend SceneOpenGLBackend)  
 if(HAVE_GBM)
     target_link_libraries(KWinWaylandDrmBackend gbm::gbm)
diff --git a/plugins/platforms/drm/egl_gbm_backend.cpp \
b/plugins/platforms/drm/egl_gbm_backend.cpp index 646e77566..685bf065d 100644
--- a/plugins/platforms/drm/egl_gbm_backend.cpp
+++ b/plugins/platforms/drm/egl_gbm_backend.cpp
@@ -253,7 +253,7 @@ void EglGbmBackend::screenGeometryChanged(const QSize &size)
     // TODO, create new buffer?
 }
 
-SceneOpenGL::TexturePrivate \
*EglGbmBackend::createBackendTexture(SceneOpenGL::Texture *texture) \
+SceneOpenGLTexturePrivate *EglGbmBackend::createBackendTexture(SceneOpenGLTexture \
*texture)  {
     return new EglGbmTexture(texture, this);
 }
@@ -343,7 +343,7 @@ bool EglGbmBackend::perScreenRendering() const
  * EglTexture
  ************************************************/
 
-EglGbmTexture::EglGbmTexture(KWin::SceneOpenGL::Texture *texture, EglGbmBackend \
*backend) +EglGbmTexture::EglGbmTexture(KWin::SceneOpenGLTexture *texture, \
EglGbmBackend *backend)  : AbstractEglTexture(texture, backend)
 {
 }
diff --git a/plugins/platforms/drm/egl_gbm_backend.h \
b/plugins/platforms/drm/egl_gbm_backend.h index 30e17e682..490ee14f0 100644
--- a/plugins/platforms/drm/egl_gbm_backend.h
+++ b/plugins/platforms/drm/egl_gbm_backend.h
@@ -20,7 +20,6 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #ifndef KWIN_EGL_GBM_BACKEND_H
 #define KWIN_EGL_GBM_BACKEND_H
 #include "abstract_egl_backend.h"
-#include "scene_opengl.h"
 
 struct gbm_surface;
 
@@ -40,7 +39,7 @@ public:
     EglGbmBackend(DrmBackend *b);
     virtual ~EglGbmBackend();
     void screenGeometryChanged(const QSize &size) override;
-    SceneOpenGL::TexturePrivate *createBackendTexture(SceneOpenGL::Texture *texture) \
override; +    SceneOpenGLTexturePrivate *createBackendTexture(SceneOpenGLTexture \
*texture) override;  QRegion prepareRenderingFrame() override;
     void endRenderingFrame(const QRegion &renderedRegion, const QRegion \
                &damagedRegion) override;
     void endRenderingFrameForScreen(int screenId, const QRegion &damage, const \
QRegion &damagedRegion) override; @@ -87,7 +86,7 @@ public:
 
 private:
     friend class EglGbmBackend;
-    EglGbmTexture(SceneOpenGL::Texture *texture, EglGbmBackend *backend);
+    EglGbmTexture(SceneOpenGLTexture *texture, EglGbmBackend *backend);
 };
 
 } // namespace
diff --git a/plugins/platforms/hwcomposer/CMakeLists.txt \
b/plugins/platforms/hwcomposer/CMakeLists.txt index 9b2405587..85d7c04ba 100644
--- a/plugins/platforms/hwcomposer/CMakeLists.txt
+++ b/plugins/platforms/hwcomposer/CMakeLists.txt
@@ -5,12 +5,14 @@ set(HWCOMPOSER_SOURCES
     screens_hwcomposer.cpp
 )
 
+include_directories(${CMAKE_SOURCE_DIR}/platformsupport/scenes/opengl)
 add_library(KWinWaylandHwcomposerBackend MODULE ${HWCOMPOSER_SOURCES})
 target_link_libraries(KWinWaylandHwcomposerBackend
     kwin
     libhybris::libhardware
     libhybris::hwcomposer
     libhybris::hybriseglplatform
+    SceneOpenGLBackend
 )
 
 install(
diff --git a/plugins/platforms/hwcomposer/egl_hwcomposer_backend.cpp \
b/plugins/platforms/hwcomposer/egl_hwcomposer_backend.cpp index 7b649bf8e..3c96db118 \
                100644
--- a/plugins/platforms/hwcomposer/egl_hwcomposer_backend.cpp
+++ b/plugins/platforms/hwcomposer/egl_hwcomposer_backend.cpp
@@ -164,7 +164,7 @@ void EglHwcomposerBackend::endRenderingFrame(const QRegion \
&renderedRegion, cons  setLastDamage(renderedRegion);
 }
 
-SceneOpenGL::TexturePrivate \
*EglHwcomposerBackend::createBackendTexture(SceneOpenGL::Texture *texture) \
+SceneOpenGLTexturePrivate \
*EglHwcomposerBackend::createBackendTexture(SceneOpenGLTexture *texture)  {
     return new EglHwcomposerTexture(texture, this);
 }
@@ -174,7 +174,7 @@ bool EglHwcomposerBackend::usesOverlayWindow() const
     return false;
 }
 
-EglHwcomposerTexture::EglHwcomposerTexture(SceneOpenGL::Texture *texture, \
EglHwcomposerBackend *backend) \
+EglHwcomposerTexture::EglHwcomposerTexture(SceneOpenGLTexture *texture, \
EglHwcomposerBackend *backend)  : AbstractEglTexture(texture, backend)
 {
 }
diff --git a/plugins/platforms/hwcomposer/egl_hwcomposer_backend.h \
b/plugins/platforms/hwcomposer/egl_hwcomposer_backend.h index 1fbbaabfa..3270104d6 \
                100644
--- a/plugins/platforms/hwcomposer/egl_hwcomposer_backend.h
+++ b/plugins/platforms/hwcomposer/egl_hwcomposer_backend.h
@@ -33,7 +33,7 @@ public:
     EglHwcomposerBackend(HwcomposerBackend *backend);
     virtual ~EglHwcomposerBackend();
     bool usesOverlayWindow() const override;
-    SceneOpenGL::TexturePrivate *createBackendTexture(SceneOpenGL::Texture *texture) \
override; +    SceneOpenGLTexturePrivate *createBackendTexture(SceneOpenGLTexture \
*texture) override;  void screenGeometryChanged(const QSize &size) override;
     QRegion prepareRenderingFrame() override;
     void endRenderingFrame(const QRegion &renderedRegion, const QRegion \
&damagedRegion) override; @@ -58,7 +58,7 @@ public:
 
 private:
     friend class EglHwcomposerBackend;
-    EglHwcomposerTexture(SceneOpenGL::Texture *texture, EglHwcomposerBackend \
*backend); +    EglHwcomposerTexture(SceneOpenGLTexture *texture, \
EglHwcomposerBackend *backend);  };
 
 }
diff --git a/plugins/platforms/virtual/CMakeLists.txt \
b/plugins/platforms/virtual/CMakeLists.txt index 24923620b..665463376 100644
--- a/plugins/platforms/virtual/CMakeLists.txt
+++ b/plugins/platforms/virtual/CMakeLists.txt
@@ -5,6 +5,7 @@ set(VIRTUAL_SOURCES
     screens_virtual.cpp
 )
 
+include_directories(${CMAKE_SOURCE_DIR}/platformsupport/scenes/opengl)
 include(ECMQtDeclareLoggingCategory)
 ecm_qt_declare_logging_category(VIRTUAL_SOURCES HEADER logging.h IDENTIFIER \
KWIN_VIRTUAL CATEGORY_NAME kwin_platform_virtual DEFAULT_SEVERITY Critical)  
@@ -12,7 +13,7 @@ add_library(KWinWaylandVirtualBackend MODULE ${VIRTUAL_SOURCES})
 target_link_libraries(KWinWaylandVirtualBackend kwin SceneQPainterBackend)
 
 if(HAVE_GBM)
-    target_link_libraries(KWinWaylandVirtualBackend gbm::gbm)
+    target_link_libraries(KWinWaylandVirtualBackend SceneOpenGLBackend gbm::gbm)
 endif()
 
 install(
diff --git a/plugins/platforms/virtual/egl_gbm_backend.cpp \
b/plugins/platforms/virtual/egl_gbm_backend.cpp index 87a064db8..b4698a23f 100644
--- a/plugins/platforms/virtual/egl_gbm_backend.cpp
+++ b/plugins/platforms/virtual/egl_gbm_backend.cpp
@@ -29,6 +29,7 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #include <logging.h>
 // kwin libs
 #include <kwinglplatform.h>
+#include <kwinglutils.h>
 // Qt
 #include <QOpenGLContext>
 // system
@@ -214,7 +215,7 @@ void EglGbmBackend::screenGeometryChanged(const QSize &size)
     // TODO, create new buffer?
 }
 
-SceneOpenGL::TexturePrivate \
*EglGbmBackend::createBackendTexture(SceneOpenGL::Texture *texture) \
+SceneOpenGLTexturePrivate *EglGbmBackend::createBackendTexture(SceneOpenGLTexture \
*texture)  {
     return new EglGbmTexture(texture, this);
 }
@@ -282,7 +283,7 @@ bool EglGbmBackend::usesOverlayWindow() const
  * EglTexture
  ************************************************/
 
-EglGbmTexture::EglGbmTexture(KWin::SceneOpenGL::Texture *texture, EglGbmBackend \
*backend) +EglGbmTexture::EglGbmTexture(KWin::SceneOpenGLTexture *texture, \
EglGbmBackend *backend)  : AbstractEglTexture(texture, backend)
 {
 }
diff --git a/plugins/platforms/virtual/egl_gbm_backend.h \
b/plugins/platforms/virtual/egl_gbm_backend.h index b4560ed25..3940e9e24 100644
--- a/plugins/platforms/virtual/egl_gbm_backend.h
+++ b/plugins/platforms/virtual/egl_gbm_backend.h
@@ -20,7 +20,6 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #ifndef KWIN_EGL_GBM_BACKEND_H
 #define KWIN_EGL_GBM_BACKEND_H
 #include "abstract_egl_backend.h"
-#include "scene_opengl.h"
 
 namespace KWin
 {
@@ -37,7 +36,7 @@ public:
     EglGbmBackend(VirtualBackend *b);
     virtual ~EglGbmBackend();
     void screenGeometryChanged(const QSize &size) override;
-    SceneOpenGL::TexturePrivate *createBackendTexture(SceneOpenGL::Texture *texture) \
override; +    SceneOpenGLTexturePrivate *createBackendTexture(SceneOpenGLTexture \
*texture) override;  QRegion prepareRenderingFrame() override;
     void endRenderingFrame(const QRegion &renderedRegion, const QRegion \
&damagedRegion) override;  bool usesOverlayWindow() const override;
@@ -68,7 +67,7 @@ public:
 
 private:
     friend class EglGbmBackend;
-    EglGbmTexture(SceneOpenGL::Texture *texture, EglGbmBackend *backend);
+    EglGbmTexture(SceneOpenGLTexture *texture, EglGbmBackend *backend);
 };
 
 } // namespace
diff --git a/plugins/platforms/virtual/virtual_backend.cpp \
b/plugins/platforms/virtual/virtual_backend.cpp index c8b20d6d5..1f2c384ae 100644
--- a/plugins/platforms/virtual/virtual_backend.cpp
+++ b/plugins/platforms/virtual/virtual_backend.cpp
@@ -29,6 +29,7 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  // system
 #include <fcntl.h>
 #include <unistd.h>
+#include <config-kwin.h>
 #if HAVE_GBM
 #include <gbm.h>
 #endif
diff --git a/plugins/platforms/wayland/CMakeLists.txt \
b/plugins/platforms/wayland/CMakeLists.txt index bdef9cff2..1fc8e3639 100644
--- a/plugins/platforms/wayland/CMakeLists.txt
+++ b/plugins/platforms/wayland/CMakeLists.txt
@@ -8,11 +8,12 @@ if(HAVE_WAYLAND_EGL)
     set(WAYLAND_BACKEND_SOURCES egl_wayland_backend.cpp ${WAYLAND_BACKEND_SOURCES})
 endif()
 
+include_directories(${CMAKE_SOURCE_DIR}/platformsupport/scenes/opengl)
 add_library(KWinWaylandWaylandBackend MODULE ${WAYLAND_BACKEND_SOURCES})
 target_link_libraries(KWinWaylandWaylandBackend kwin KF5::WaylandClient \
SceneQPainterBackend)  
 if(HAVE_WAYLAND_EGL)
-    target_link_libraries(KWinWaylandWaylandBackend Wayland::Egl)
+    target_link_libraries(KWinWaylandWaylandBackend SceneOpenGLBackend Wayland::Egl)
 endif()
 
 install(
diff --git a/plugins/platforms/wayland/egl_wayland_backend.cpp \
b/plugins/platforms/wayland/egl_wayland_backend.cpp index 3107780f3..16f64888b 100644
--- a/plugins/platforms/wayland/egl_wayland_backend.cpp
+++ b/plugins/platforms/wayland/egl_wayland_backend.cpp
@@ -213,7 +213,7 @@ void EglWaylandBackend::screenGeometryChanged(const QSize &size)
     m_bufferAge = 0;
 }
 
-SceneOpenGL::TexturePrivate \
*EglWaylandBackend::createBackendTexture(SceneOpenGL::Texture *texture) \
+SceneOpenGLTexturePrivate \
*EglWaylandBackend::createBackendTexture(SceneOpenGLTexture *texture)  {
     return new EglWaylandTexture(texture, this);
 }
@@ -280,7 +280,7 @@ bool EglWaylandBackend::usesOverlayWindow() const
  * EglTexture
  ************************************************/
 
-EglWaylandTexture::EglWaylandTexture(KWin::SceneOpenGL::Texture *texture, \
KWin::EglWaylandBackend *backend) \
+EglWaylandTexture::EglWaylandTexture(KWin::SceneOpenGLTexture *texture, \
KWin::EglWaylandBackend *backend)  : AbstractEglTexture(texture, backend)
 {
 }
diff --git a/plugins/platforms/wayland/egl_wayland_backend.h \
b/plugins/platforms/wayland/egl_wayland_backend.h index 0b2893d86..e42da7df3 100644
--- a/plugins/platforms/wayland/egl_wayland_backend.h
+++ b/plugins/platforms/wayland/egl_wayland_backend.h
@@ -20,7 +20,6 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #ifndef KWIN_EGL_WAYLAND_BACKEND_H
 #define KWIN_EGL_WAYLAND_BACKEND_H
 #include "abstract_egl_backend.h"
-#include "scene_opengl.h"
 // wayland
 #include <wayland-egl.h>
 
@@ -54,7 +53,7 @@ public:
     EglWaylandBackend(Wayland::WaylandBackend *b);
     virtual ~EglWaylandBackend();
     virtual void screenGeometryChanged(const QSize &size);
-    virtual SceneOpenGL::TexturePrivate *createBackendTexture(SceneOpenGL::Texture \
*texture); +    virtual SceneOpenGLTexturePrivate \
*createBackendTexture(SceneOpenGLTexture *texture) override;  virtual QRegion \
                prepareRenderingFrame();
     virtual void endRenderingFrame(const QRegion &renderedRegion, const QRegion \
&damagedRegion);  virtual bool usesOverlayWindow() const override;
@@ -88,7 +87,7 @@ public:
 
 private:
     friend class EglWaylandBackend;
-    EglWaylandTexture(SceneOpenGL::Texture *texture, EglWaylandBackend *backend);
+    EglWaylandTexture(SceneOpenGLTexture *texture, EglWaylandBackend *backend);
 };
 
 } // namespace
diff --git a/plugins/platforms/x11/common/CMakeLists.txt \
b/plugins/platforms/x11/common/CMakeLists.txt index 5a1ab6d0a..677f9f6c9 100644
--- a/plugins/platforms/x11/common/CMakeLists.txt
+++ b/plugins/platforms/x11/common/CMakeLists.txt
@@ -4,5 +4,6 @@ endif()
 if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-int-to-void-pointer-cast")
 endif()
+include_directories(${CMAKE_SOURCE_DIR}/platformsupport/scenes/opengl)
 add_library(eglx11common STATIC eglonxbackend.cpp)
 target_link_libraries(eglx11common kwin)
diff --git a/plugins/platforms/x11/common/eglonxbackend.cpp \
b/plugins/platforms/x11/common/eglonxbackend.cpp index 6eaf518a3..1990fc49b 100644
--- a/plugins/platforms/x11/common/eglonxbackend.cpp
+++ b/plugins/platforms/x11/common/eglonxbackend.cpp
@@ -23,11 +23,15 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #include "options.h"
 #include "overlaywindow.h"
 #include "platform.h"
+#include "scene.h"
 #include "screens.h"
 #include "xcbutils.h"
+#include "texture.h"
 // kwin libs
 #include <kwinglplatform.h>
+#include <kwinglutils.h>
 // Qt
+#include <QLoggingCategory>
 #include <QDebug>
 #include <QOpenGLContext>
 // system
@@ -386,7 +390,7 @@ void EglOnXBackend::screenGeometryChanged(const QSize &size)
     m_bufferAge = 0;
 }
 
-SceneOpenGL::TexturePrivate \
*EglOnXBackend::createBackendTexture(SceneOpenGL::Texture *texture) \
+SceneOpenGLTexturePrivate *EglOnXBackend::createBackendTexture(SceneOpenGLTexture \
*texture)  {
     return new EglTexture(texture, this);
 }
@@ -473,7 +477,7 @@ bool EglOnXBackend::makeContextCurrent(const EGLSurface &surface)
  * EglTexture
  ************************************************/
 
-EglTexture::EglTexture(KWin::SceneOpenGL::Texture *texture, KWin::EglOnXBackend \
*backend) +EglTexture::EglTexture(KWin::SceneOpenGLTexture *texture, \
KWin::EglOnXBackend *backend)  : AbstractEglTexture(texture, backend)
     , m_backend(backend)
 {
diff --git a/plugins/platforms/x11/common/eglonxbackend.h \
b/plugins/platforms/x11/common/eglonxbackend.h index 941f660d6..0063971bf 100644
--- a/plugins/platforms/x11/common/eglonxbackend.h
+++ b/plugins/platforms/x11/common/eglonxbackend.h
@@ -20,7 +20,9 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #ifndef KWIN_EGL_ON_X_BACKEND_H
 #define KWIN_EGL_ON_X_BACKEND_H
 #include "abstract_egl_backend.h"
-#include "scene_opengl.h"
+#include "swap_profiler.h"
+
+#include <xcb/xcb.h>
 
 namespace KWin
 {
@@ -35,7 +37,7 @@ public:
     explicit EglOnXBackend(xcb_connection_t *connection, Display *display, \
xcb_window_t rootWindow, int screenNumber, xcb_window_t renderingWindow);  virtual \
~EglOnXBackend();  virtual void screenGeometryChanged(const QSize &size);
-    virtual SceneOpenGL::TexturePrivate *createBackendTexture(SceneOpenGL::Texture \
*texture); +    virtual SceneOpenGLTexturePrivate \
*createBackendTexture(SceneOpenGLTexture *texture) override;  virtual QRegion \
                prepareRenderingFrame();
     virtual void endRenderingFrame(const QRegion &damage, const QRegion \
&damagedRegion);  virtual OverlayWindow* overlayWindow() override;
@@ -80,6 +82,7 @@ private:
     xcb_window_t m_renderingWindow = XCB_WINDOW_NONE;
     bool m_havePlatformBase = false;
     bool m_x11TextureFromPixmapSupported = true;
+    SwapProfiler m_swapProfiler;
     friend class EglTexture;
 };
 
@@ -96,7 +99,7 @@ public:
 private:
     bool loadTexture(xcb_pixmap_t pix, const QSize &size);
     friend class EglOnXBackend;
-    EglTexture(SceneOpenGL::Texture *texture, EglOnXBackend *backend);
+    EglTexture(SceneOpenGLTexture *texture, EglOnXBackend *backend);
     EglOnXBackend *m_backend;
 };
 
diff --git a/plugins/platforms/x11/standalone/CMakeLists.txt \
b/plugins/platforms/x11/standalone/CMakeLists.txt index 260987019..66e878cfc 100644
--- a/plugins/platforms/x11/standalone/CMakeLists.txt
+++ b/plugins/platforms/x11/standalone/CMakeLists.txt
@@ -20,8 +20,10 @@ if(HAVE_EPOXY_GLX)
     set(X11PLATFORM_SOURCES ${X11PLATFORM_SOURCES} glxbackend.cpp \
glx_context_attribute_builder.cpp)  endif()
 
+include_directories(${CMAKE_SOURCE_DIR}/platformsupport/scenes/opengl)
+
 add_library(KWinX11Platform MODULE ${X11PLATFORM_SOURCES})
-target_link_libraries(KWinX11Platform eglx11common kwin kwinxrenderutils \
Qt5::X11Extras XCB::CURSOR) +target_link_libraries(KWinX11Platform eglx11common kwin \
kwinxrenderutils SceneOpenGLBackend Qt5::X11Extras XCB::CURSOR)  if(X11_Xinput_FOUND)
     target_link_libraries(KWinX11Platform ${X11_Xinput_LIB})
 endif()
diff --git a/plugins/platforms/x11/standalone/glxbackend.cpp \
b/plugins/platforms/x11/standalone/glxbackend.cpp index f61bb6801..ff22ec719 100644
--- a/plugins/platforms/x11/standalone/glxbackend.cpp
+++ b/plugins/platforms/x11/standalone/glxbackend.cpp
@@ -31,10 +31,13 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #include "overlaywindow.h"
 #include "composite.h"
 #include "platform.h"
+#include "scene.h"
 #include "screens.h"
 #include "xcbutils.h"
+#include "texture.h"
 // kwin libs
 #include <kwinglplatform.h>
+#include <kwinglutils.h>
 #include <kwinxrenderutils.h>
 // Qt
 #include <QDebug>
@@ -48,6 +51,7 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #if HAVE_DL_LIBRARY
 #include <dlfcn.h>
 #endif
+#include <assert.h>
 
 #ifndef XCB_GLX_BUFFER_SWAP_COMPLETE
 #define XCB_GLX_BUFFER_SWAP_COMPLETE 1
@@ -722,7 +726,7 @@ void GlxBackend::present()
         }
     } else { // Copy Pixels (horribly slow on Mesa)
         glDrawBuffer(GL_FRONT);
-        SceneOpenGL::copyPixels(lastDamage());
+        copyPixels(lastDamage());
         glDrawBuffer(GL_BACK);
     }
 
@@ -748,7 +752,7 @@ void GlxBackend::screenGeometryChanged(const QSize &size)
     m_bufferAge = 0;
 }
 
-SceneOpenGL::TexturePrivate *GlxBackend::createBackendTexture(SceneOpenGL::Texture \
*texture) +SceneOpenGLTexturePrivate \
*GlxBackend::createBackendTexture(SceneOpenGLTexture *texture)  {
     return new GlxTexture(texture, this);
 }
@@ -844,8 +848,8 @@ bool GlxBackend::usesOverlayWindow() const
 /********************************************************
  * GlxTexture
  *******************************************************/
-GlxTexture::GlxTexture(SceneOpenGL::Texture *texture, GlxBackend *backend)
-    : SceneOpenGL::TexturePrivate()
+GlxTexture::GlxTexture(SceneOpenGLTexture *texture, GlxBackend *backend)
+    : SceneOpenGLTexturePrivate()
     , q(texture)
     , m_backend(backend)
     , m_glxpixmap(None)
diff --git a/plugins/platforms/x11/standalone/glxbackend.h \
b/plugins/platforms/x11/standalone/glxbackend.h index 59787419e..ff3a0d8f2 100644
--- a/plugins/platforms/x11/standalone/glxbackend.h
+++ b/plugins/platforms/x11/standalone/glxbackend.h
@@ -19,11 +19,14 @@ along with this program.  If not, see \
                <http://www.gnu.org/licenses/>.
 *********************************************************************/
 #ifndef KWIN_GLX_BACKEND_H
 #define KWIN_GLX_BACKEND_H
-#include "scene_opengl.h"
+#include "backend.h"
+#include "texture.h"
+#include "swap_profiler.h"
 #include "x11eventfilter.h"
 
 #include <xcb/glx.h>
 #include <epoxy/glx.h>
+#include <fixx11h.h>
 #include <memory>
 
 namespace KWin
@@ -68,7 +71,7 @@ public:
     GlxBackend(Display *display);
     virtual ~GlxBackend();
     virtual void screenGeometryChanged(const QSize &size);
-    virtual SceneOpenGL::TexturePrivate *createBackendTexture(SceneOpenGL::Texture \
*texture); +    virtual SceneOpenGLTexturePrivate \
*createBackendTexture(SceneOpenGLTexture *texture) override;  virtual QRegion \
                prepareRenderingFrame();
     virtual void endRenderingFrame(const QRegion &damage, const QRegion \
&damagedRegion);  virtual bool makeCurrent() override;
@@ -116,13 +119,14 @@ private:
     bool haveSwapInterval = false;
     bool haveWaitSync = false;
     Display *m_x11Display;
+    SwapProfiler m_swapProfiler;
     friend class GlxTexture;
 };
 
 /**
  * @brief Texture using an GLXPixmap.
  **/
-class GlxTexture : public SceneOpenGL::TexturePrivate
+class GlxTexture : public SceneOpenGLTexturePrivate
 {
 public:
     virtual ~GlxTexture();
@@ -132,12 +136,12 @@ public:
 
 private:
     friend class GlxBackend;
-    GlxTexture(SceneOpenGL::Texture *texture, GlxBackend *backend);
+    GlxTexture(SceneOpenGLTexture *texture, GlxBackend *backend);
     bool loadTexture(xcb_pixmap_t pix, const QSize &size, xcb_visualid_t visual);
     Display *display() const {
         return m_backend->m_x11Display;
     }
-    SceneOpenGL::Texture *q;
+    SceneOpenGLTexture *q;
     GlxBackend *m_backend;
     GLXPixmap m_glxpixmap; // the glx pixmap the texture is bound to
 };
diff --git a/plugins/platforms/x11/windowed/CMakeLists.txt \
b/plugins/platforms/x11/windowed/CMakeLists.txt index 1c445c5b5..8236c6b48 100644
--- a/plugins/platforms/x11/windowed/CMakeLists.txt
+++ b/plugins/platforms/x11/windowed/CMakeLists.txt
@@ -5,8 +5,9 @@ set(X11BACKEND_SOURCES
     x11windowed_backend.cpp
 )
 
+include_directories(${CMAKE_SOURCE_DIR}/platformsupport/scenes/opengl)
 add_library(KWinWaylandX11Backend MODULE ${X11BACKEND_SOURCES})
-target_link_libraries(KWinWaylandX11Backend eglx11common kwin kwinxrenderutils \
X11::XCB SceneQPainterBackend) +target_link_libraries(KWinWaylandX11Backend \
eglx11common kwin kwinxrenderutils X11::XCB SceneQPainterBackend SceneOpenGLBackend)  \
  install(
     TARGETS
diff --git a/plugins/platforms/x11/windowed/x11windowed_backend.cpp \
b/plugins/platforms/x11/windowed/x11windowed_backend.cpp index 302bac7f4..95306b027 \
                100644
--- a/plugins/platforms/x11/windowed/x11windowed_backend.cpp
+++ b/plugins/platforms/x11/windowed/x11windowed_backend.cpp
@@ -27,8 +27,10 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #include <kwinxrenderutils.h>
 // KDE
 #include <KLocalizedString>
+#include <NETWM>
 #include <QAbstractEventDispatcher>
 #include <QCoreApplication>
+#include <QIcon>
 #include <QSocketNotifier>
 // kwayland
 #include <KWayland/Server/buffer_interface.h>
diff --git a/plugins/scenes/CMakeLists.txt b/plugins/scenes/CMakeLists.txt
index 8ef7930be..eb84a43ce 100644
--- a/plugins/scenes/CMakeLists.txt
+++ b/plugins/scenes/CMakeLists.txt
@@ -1,3 +1,4 @@
+add_subdirectory(opengl)
 add_subdirectory(qpainter)
 if( KWIN_BUILD_XRENDER_COMPOSITING )
     add_subdirectory(xrender)
diff --git a/plugins/scenes/opengl/CMakeLists.txt \
b/plugins/scenes/opengl/CMakeLists.txt new file mode 100644
index 000000000..47684dfe0
--- /dev/null
+++ b/plugins/scenes/opengl/CMakeLists.txt
@@ -0,0 +1,26 @@
+set(SCENE_OPENGL_SRCS scene_opengl.cpp)
+
+include(ECMQtDeclareLoggingCategory)
+ecm_qt_declare_logging_category(
+    SCENE_OPENGL_SRCS HEADER
+        logging.h
+    IDENTIFIER
+        KWIN_OPENGL
+    CATEGORY_NAME
+        kwin_scene_opengl
+    DEFAULT_SEVERITY
+        Critical
+)
+
+add_library(KWinSceneOpenGL MODULE scene_opengl.cpp)
+target_link_libraries(KWinSceneOpenGL
+    kwin
+    SceneOpenGLBackend
+)
+
+install(
+    TARGETS
+        KWinSceneOpenGL
+    DESTINATION
+        ${PLUGIN_INSTALL_DIR}/org.kde.kwin.scenes/
+)
diff --git a/plugins/scenes/opengl/opengl.json b/plugins/scenes/opengl/opengl.json
new file mode 100644
index 000000000..e31a6d8e0
--- /dev/null
+++ b/plugins/scenes/opengl/opengl.json
@@ -0,0 +1,9 @@
+{
+    "CompositingType": 1,
+    "KPlugin": {
+        "Description": "KWin Compositor plugin rendering through OpenGL",
+        "Id": "KWinSceneOpenGL",
+        "Name": "SceneOpenGL"
+    }
+}
+
diff --git a/scene_opengl.cpp b/plugins/scenes/opengl/scene_opengl.cpp
similarity index 92%
rename from scene_opengl.cpp
rename to plugins/scenes/opengl/scene_opengl.cpp
index 66a39274f..59a385de8 100644
--- a/scene_opengl.cpp
+++ b/plugins/scenes/opengl/scene_opengl.cpp
@@ -30,6 +30,7 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  
 #include "platform.h"
 #include "wayland_server.h"
+#include "platformsupport/scenes/opengl/texture.h"
 
 #include <kwinglplatform.h>
 
@@ -44,6 +45,7 @@ along with this program.  If not, see \
<http://www.gnu.org/licenses/>.  #include "screens.h"
 #include "cursor.h"
 #include "decorations/decoratedclient.h"
+#include <logging.h>
 
 #include <KWayland/Server/subcompositor_interface.h>
 #include <KWayland/Server/surface_interface.h>
@@ -180,18 +182,18 @@ bool SyncObject::finish()
     glGetSynciv(m_sync, GL_SYNC_STATUS, 1, nullptr, &value);
 
     if (value != GL_SIGNALED) {
-        qCDebug(KWIN_CORE) << "Waiting for X fence to finish";
+        qCDebug(KWIN_OPENGL) << "Waiting for X fence to finish";
 
         // Wait for the fence to become signaled with a one second timeout
         const GLenum result = glClientWaitSync(m_sync, 0, 1000000000);
 
         switch (result) {
         case GL_TIMEOUT_EXPIRED:
-            qCWarning(KWIN_CORE) << "Timeout while waiting for X fence";
+            qCWarning(KWIN_OPENGL) << "Timeout while waiting for X fence";
             return false;
 
         case GL_WAIT_FAILED:
-            qCWarning(KWIN_CORE) << "glClientWaitSync() failed";
+            qCWarning(KWIN_OPENGL) << "glClientWaitSync() failed";
             return false;
         }
     }
@@ -302,85 +304,6 @@ bool SyncManager::updateFences()
 
 // -----------------------------------------------------------------------
 
-
-
-//****************************************
-// SceneOpenGL
-//****************************************
-OpenGLBackend::OpenGLBackend()
-    : m_syncsToVBlank(false)
-    , m_blocksForRetrace(false)
-    , m_directRendering(false)
-    , m_haveBufferAge(false)
-    , m_failed(false)
-{
-}
-
-OpenGLBackend::~OpenGLBackend()
-{
-}
-
-void OpenGLBackend::setFailed(const QString &reason)
-{
-    qCWarning(KWIN_CORE) << "Creating the OpenGL rendering failed: " << reason;
-    m_failed = true;
-}
-
-void OpenGLBackend::idle()
-{
-    if (hasPendingFlush()) {
-        effects->makeOpenGLContextCurrent();
-        present();
-    }
-}
-
-void OpenGLBackend::addToDamageHistory(const QRegion &region)
-{
-    if (m_damageHistory.count() > 10)
-        m_damageHistory.removeLast();
-
-    m_damageHistory.prepend(region);
-}
-
-QRegion OpenGLBackend::accumulatedDamageHistory(int bufferAge) const
-{
-    QRegion region;
-
-    // Note: An age of zero means the buffer contents are undefined
-    if (bufferAge > 0 && bufferAge <= m_damageHistory.count()) {
-        for (int i = 0; i < bufferAge - 1; i++)
-            region |= m_damageHistory[i];
-    } else {
-        const QSize &s = screens()->size();
-        region = QRegion(0, 0, s.width(), s.height());
-    }
-
-    return region;
-}
-
-OverlayWindow* OpenGLBackend::overlayWindow()
-{
-    return NULL;
-}
-
-QRegion OpenGLBackend::prepareRenderingForScreen(int screenId)
-{
-    // fallback to repaint complete screen
-    return screens()->geometry(screenId);
-}
-
-void OpenGLBackend::endRenderingFrameForScreen(int screenId, const QRegion &damage, \
                const QRegion &damagedRegion)
-{
-    Q_UNUSED(screenId)
-    Q_UNUSED(damage)
-    Q_UNUSED(damagedRegion)
-}
-
-bool OpenGLBackend::perScreenRendering() const
-{
-    return false;
-}
-
 /************************************************
  * SceneOpenGL
  ***********************************************/
@@ -403,12 +326,12 @@ SceneOpenGL::SceneOpenGL(OpenGLBackend *backend, QObject \
*parent)  GLPlatform *glPlatform = GLPlatform::instance();
     if (!glPlatform->isGLES() && \
                !hasGLExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"))
             && !hasGLExtension(QByteArrayLiteral("GL_ARB_texture_rectangle"))) {
-        qCCritical(KWIN_CORE) << "GL_ARB_texture_non_power_of_two and \
GL_ARB_texture_rectangle missing"; +        qCCritical(KWIN_OPENGL) << \
"GL_ARB_texture_non_power_of_two and GL_ARB_texture_rectangle missing";  init_ok = \
false;  return; // error
     }
     if (glPlatform->isMesaDriver() && glPlatform->mesaVersion() < kVersionNumber(10, \
                0)) {
-        qCCritical(KWIN_CORE) << "KWin requires at least Mesa 10.0 for OpenGL \
compositing."; +        qCCritical(KWIN_OPENGL) << "KWin requires at least Mesa 10.0 \
for OpenGL compositing.";  init_ok = false;
         return;
     }
@@ -432,10 +355,10 @@ SceneOpenGL::SceneOpenGL(OpenGLBackend *backend, QObject \
*parent)  const QByteArray useExplicitSync = qgetenv("KWIN_EXPLICIT_SYNC");
 
         if (useExplicitSync != "0") {
-            qCDebug(KWIN_CORE) << "Initializing fences for synchronization with the \
X command stream"; +            qCDebug(KWIN_OPENGL) << "Initializing fences for \
synchronization with the X command stream";  m_syncManager = new SyncManager;
         } else {
-            qCDebug(KWIN_CORE) << "Explicit synchronization with the X command \
stream disabled by environment variable"; +            qCDebug(KWIN_OPENGL) << \
"Explicit synchronization with the X command stream disabled by environment \
variable";  }
     }
 }
@@ -514,7 +437,7 @@ void SceneOpenGL::initDebugOutput()
         switch (type) {
         case GL_DEBUG_TYPE_ERROR:
         case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
-            qCWarning(KWIN_CORE, "%#x: %.*s", id, length, message);
+            qCWarning(KWIN_OPENGL, "%#x: %.*s", id, length, message);
             break;
 
         case GL_DEBUG_TYPE_OTHER:
@@ -532,7 +455,7 @@ void SceneOpenGL::initDebugOutput()
         case GL_DEBUG_TYPE_PORTABILITY:
         case GL_DEBUG_TYPE_PERFORMANCE:
         default:
-            qCDebug(KWIN_CORE, "%#x: %.*s", id, length, message);
+            qCDebug(KWIN_OPENGL, "%#x: %.*s", id, length, message);
             break;
         }
     };
@@ -584,9 +507,9 @@ SceneOpenGL *SceneOpenGL::createScene(QObject *parent)
     }
     if (!scene) {
         if (GLPlatform::instance()->recommendedCompositor() == XRenderCompositing) {
-            qCCritical(KWIN_CORE) << "OpenGL driver recommends XRender based \
                compositing. Falling back to XRender.";
-            qCCritical(KWIN_CORE) << "To overwrite the detection use the environment \
                variable KWIN_COMPOSE";
-            qCCritical(KWIN_CORE) << "For more information see \
http://community.kde.org/KWin/Environment_Variables#KWIN_COMPOSE"; +            \
qCCritical(KWIN_OPENGL) << "OpenGL driver recommends XRender based compositing. \
Falling back to XRender."; +            qCCritical(KWIN_OPENGL) << "To overwrite the \
detection use the environment variable KWIN_COMPOSE"; +            \
qCCritical(KWIN_OPENGL) << "For more information see \
                http://community.kde.org/KWin/Environment_Variables#KWIN_COMPOSE";
             QTimer::singleShot(0, Compositor::self(), \
SLOT(fallbackToXRenderCompositing()));  }
         delete backend;
@@ -621,32 +544,19 @@ bool SceneOpenGL::initFailed() const
     return !init_ok;
 }
 
-void SceneOpenGL::copyPixels(const QRegion &region)
-{
-    const int height = screens()->size().height();
-    foreach (const QRect &r, region.rects()) {
-        const int x0 = r.x();
-        const int y0 = height - r.y() - r.height();
-        const int x1 = r.x() + r.width();
-        const int y1 = height - r.y();
-
-        glBlitFramebuffer(x0, y0, x1, y1, x0, y0, x1, y1, GL_COLOR_BUFFER_BIT, \
                GL_NEAREST);
-    }
-}
-
 void SceneOpenGL::handleGraphicsReset(GLenum status)
 {
     switch (status) {
     case GL_GUILTY_CONTEXT_RESET:
-        qCDebug(KWIN_CORE) << "A graphics reset attributable to the current GL \
context occurred."; +        qCDebug(KWIN_OPENGL) << "A graphics reset attributable \
to the current GL context occurred.";  break;
 
     case GL_INNOCENT_CONTEXT_RESET:
-        qCDebug(KWIN_CORE) << "A graphics reset not attributable to the current GL \
context occurred."; +        qCDebug(KWIN_OPENGL) << "A graphics reset not \
attributable to the current GL context occurred.";  break;
 
     case GL_UNKNOWN_CONTEXT_RESET:
-        qCDebug(KWIN_CORE) << "A graphics reset of an unknown cause occurred.";
+        qCDebug(KWIN_OPENGL) << "A graphics reset of an unknown cause occurred.";
         break;
 
     default:
@@ -660,7 +570,7 @@ void SceneOpenGL::handleGraphicsReset(GLenum status)
     while (timer.elapsed() < 10000 && glGetGraphicsResetStatus() != GL_NO_ERROR)
         usleep(50);
 
-    qCDebug(KWIN_CORE) << "Attempting to reset compositing.";
+    qCDebug(KWIN_OPENGL) << "Attempting to reset compositing.";
     QMetaObject::invokeMethod(this, "resetCompositing", Qt::QueuedConnection);
 
     KNotification::event(QStringLiteral("graphicsreset"), i18n("Desktop effects were \
restarted due to a graphics reset")); @@ -800,7 +710,7 @@ qint64 \
                SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
                 options->glPreferBufferSwap() == Options::CopyFrontBuffer &&
                 validRegion != displayRegion) {
                 glReadBuffer(GL_FRONT);
-                copyPixels(displayRegion - validRegion);
+                m_backend->copyPixels(displayRegion - validRegion);
                 glReadBuffer(GL_BACK);
                 validRegion = displayRegion;
             }
@@ -815,8 +725,8 @@ qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
 
     if (m_currentFence) {
         if (!m_syncManager->updateFences()) {
-            qCDebug(KWIN_CORE) << "Aborting explicit synchronization with the X \
                command stream.";
-            qCDebug(KWIN_CORE) << "Future frames will be rendered unsynchronized.";
+            qCDebug(KWIN_OPENGL) << "Aborting explicit synchronization with the X \
command stream."; +            qCDebug(KWIN_OPENGL) << "Future frames will be \
rendered unsynchronized.";  delete m_syncManager;
             m_syncManager = nullptr;
         }
@@ -902,9 +812,9 @@ void SceneOpenGL::extendPaintRegion(QRegion &region, bool \
opaqueFullscreen)  }
 }
 
-SceneOpenGL::Texture *SceneOpenGL::createTexture()
+SceneOpenGLTexture *SceneOpenGL::createTexture()
 {
-    return new Texture(m_backend);
+    return new SceneOpenGLTexture(m_backend);
 }
 
 bool SceneOpenGL::viewportLimitsMatched(const QSize &size) const {
@@ -1034,7 +944,7 @@ bool SceneOpenGL2::supported(OpenGLBackend *backend)
     const QByteArray forceEnv = qgetenv("KWIN_COMPOSE");
     if (!forceEnv.isEmpty()) {
         if (qstrcmp(forceEnv, "O2") == 0 || qstrcmp(forceEnv, "O2ES") == 0) {
-            qCDebug(KWIN_CORE) << "OpenGL 2 compositing enforced by environment \
variable"; +            qCDebug(KWIN_OPENGL) << "OpenGL 2 compositing enforced by \
environment variable";  return true;
         } else {
             // OpenGL 2 disabled by environment variable
@@ -1045,7 +955,7 @@ bool SceneOpenGL2::supported(OpenGLBackend *backend)
         return false;
     }
     if (GLPlatform::instance()->recommendedCompositor() < OpenGL2Compositing) {
-        qCDebug(KWIN_CORE) << "Driver does not recommend OpenGL 2 compositing";
+        qCDebug(KWIN_OPENGL) << "Driver does not recommend OpenGL 2 compositing";
         return false;
     }
     return true;
@@ -1062,7 +972,7 @@ SceneOpenGL2::SceneOpenGL2(OpenGLBackend *backend, QObject \
*parent)  
     // We only support the OpenGL 2+ shader API, not GL_ARB_shader_objects
     if (!hasGLVersion(2, 0)) {
-        qCDebug(KWIN_CORE) << "OpenGL 2.0 is not supported";
+        qCDebug(KWIN_OPENGL) << "OpenGL 2.0 is not supported";
         init_ok = false;
         return;
     }
@@ -1074,7 +984,7 @@ SceneOpenGL2::SceneOpenGL2(OpenGLBackend *backend, QObject \
*parent)  // push one shader on the stack so that one is always bound
     ShaderManager::instance()->pushShader(ShaderTrait::MapTexture);
     if (checkGLError("Init")) {
-        qCCritical(KWIN_CORE) << "OpenGL 2 compositing setup failed";
+        qCCritical(KWIN_OPENGL) << "OpenGL 2 compositing setup failed";
         init_ok = false;
         return; // error
     }
@@ -1086,12 +996,12 @@ SceneOpenGL2::SceneOpenGL2(OpenGLBackend *backend, QObject \
*parent)  }
 
     if (!ShaderManager::instance()->selfTest()) {
-        qCCritical(KWIN_CORE) << "ShaderManager self test failed";
+        qCCritical(KWIN_OPENGL) << "ShaderManager self test failed";
         init_ok = false;
         return;
     }
 
-    qCDebug(KWIN_CORE) << "OpenGL 2 compositing successfully initialized";
+    qCDebug(KWIN_OPENGL) << "OpenGL 2 compositing successfully initialized";
     init_ok = true;
 }
 
@@ -1198,65 +1108,6 @@ void SceneOpenGL2::performPaintWindow(EffectWindowImpl* w, int \
mask, QRegion reg  w->sceneWindow()->performPaint(mask, region, data);
 }
 
-//****************************************
-// SceneOpenGL::Texture
-//****************************************
-
-SceneOpenGL::Texture::Texture(OpenGLBackend *backend)
-    : GLTexture(*backend->createBackendTexture(this))
-{
-}
-
-SceneOpenGL::Texture::~Texture()
-{
-}
-
-SceneOpenGL::Texture& SceneOpenGL::Texture::operator = (const SceneOpenGL::Texture& \
                tex)
-{
-    d_ptr = tex.d_ptr;
-    return *this;
-}
-
-void SceneOpenGL::Texture::discard()
-{
-    d_ptr = d_func()->backend()->createBackendTexture(this);
-}
-
-bool SceneOpenGL::Texture::load(WindowPixmap *pixmap)
-{
-    if (!pixmap->isValid()) {
-        return false;
-    }
-
-    // decrease the reference counter for the old texture
-    d_ptr = d_func()->backend()->createBackendTexture(this); //new TexturePrivate();
-
-    Q_D(Texture);
-    return d->loadTexture(pixmap);
-}
-
-void SceneOpenGL::Texture::updateFromPixmap(WindowPixmap *pixmap)
-{
-    Q_D(Texture);
-    d->updateTexture(pixmap);
-}
-
-//****************************************
-// SceneOpenGL::Texture
-//****************************************
-SceneOpenGL::TexturePrivate::TexturePrivate()
-{
-}
-
-SceneOpenGL::TexturePrivate::~TexturePrivate()
-{
-}
-
-void SceneOpenGL::TexturePrivate::updateTexture(WindowPixmap *pixmap)
-{
-    Q_UNUSED(pixmap)
-}
-
 //****************************************
 // SceneOpenGL::Window
 //****************************************
@@ -1271,7 +1122,7 @@ SceneOpenGL::Window::~Window()
 {
 }
 
-static SceneOpenGL::Texture *s_frameTexture = NULL;
+static SceneOpenGLTexture *s_frameTexture = NULL;
 // Bind the window pixmap to an OpenGL texture.
 bool SceneOpenGL::Window::bindTexture()
 {
@@ -1748,7 +1599,7 @@ bool OpenGLWindowPixmap::bind()
             toplevel()->resetDamage();
         }
     } else
-        qCDebug(KWIN_CORE) << "Failed to bind window";
+        qCDebug(KWIN_OPENGL) << "Failed to bind window";
     return success;
 }
 
@@ -2473,36 +2324,6 @@ bool SceneOpenGLShadow::prepareBackend()
     return true;
 }
 
-SwapProfiler::SwapProfiler()
-{
-    init();
-}
-
-void SwapProfiler::init()
-{
-    m_time = 2 * 1000*1000; // we start with a long time mean of 2ms ...
-    m_counter = 0;
-}
-
-void SwapProfiler::begin()
-{
-    m_timer.start();
-}
-
-char SwapProfiler::end()
-{
-    // .. and blend in actual values.
-    // this way we prevent extremes from killing our long time mean
-    m_time = (10*m_time + m_timer.nsecsElapsed())/11;
-    if (++m_counter > 500) {
-        const bool blocks = m_time > 1000 * 1000; // 1ms, i get ~250 µs and ~7ms w/o \
                triple buffering...
-        qCDebug(KWIN_CORE) << "Triple buffering detection:" << QString(blocks ? \
                QStringLiteral("NOT available") : QStringLiteral("Available")) <<
-                        " - Mean block time:" << m_time/(1000.0*1000.0) << "ms";
-        return blocks ? 'd' : 't';
-    }
-    return 0;
-}
-
 SceneOpenGLDecorationRenderer::SceneOpenGLDecorationRenderer(Decoration::DecoratedClientImpl \
*client)  : Renderer(client)
     , m_texture()
@@ -2610,4 +2431,31 @@ void SceneOpenGLDecorationRenderer::reparent(Deleted *deleted)
     Renderer::reparent(deleted);
 }
 
+
+OpenGLFactory::OpenGLFactory(QObject *parent)
+    : SceneFactory(parent)
+{
+}
+
+OpenGLFactory::~OpenGLFactory() = default;
+
+Scene *OpenGLFactory::create(QObject *parent) const
+{
+    qCDebug(KWIN_OPENGL) << "Initializing OpenGL compositing";
+
+    // Some broken drivers crash on glXQuery() so to prevent constant KWin crashes:
+    if (kwinApp()->platform()->openGLCompositingIsBroken()) {
+        qCWarning(KWIN_OPENGL) << "KWin has detected that your OpenGL library is \
unsafe to use"; +        return nullptr;
+    }
+    kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PreInit);
 +    auto s = SceneOpenGL::createScene(parent);
+    kwinApp()->platform()->createOpenGLSafePoint(Platform::OpenGLSafePoint::PostInit);
 +    if (s && s->initFailed()) {
+        delete s;
+        return nullptr;
+    }
+    return s;
+}
+
 } // namespace
diff --git a/plugins/scenes/opengl/scene_opengl.h \
b/plugins/scenes/opengl/scene_opengl.h new file mode 100644
index 000000000..6643dc353
--- /dev/null
+++ b/plugins/scenes/opengl/scene_opengl.h
@@ -0,0 +1,354 @@
+/********************************************************************
+ KWin - the KDE window manager
+ This file is part of the KDE project.
+
+Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
+Copyright (C) 2009, 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
+
+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 <http://www.gnu.org/licenses/>.
+*********************************************************************/
+
+#ifndef KWIN_SCENE_OPENGL_H
+#define KWIN_SCENE_OPENGL_H
+
+#include "scene.h"
+#include "shadow.h"
+
+#include "kwinglutils.h"
+
+#include "decorations/decorationrenderer.h"
+#include "platformsupport/scenes/opengl/backend.h"
+
+namespace KWin
+{
+class LanczosFilter;
+class OpenGLBackend;
+class SyncManager;
+class SyncObject;
+
+class KWIN_EXPORT SceneOpenGL
+    : public Scene
+{
+    Q_OBJECT
+public:
+    class EffectFrame;
+    class Window;
+    virtual ~SceneOpenGL();
+    virtual bool initFailed() const;
+    virtual bool hasPendingFlush() const;
+    virtual qint64 paint(QRegion damage, ToplevelList windows);
+    virtual Scene::EffectFrame *createEffectFrame(EffectFrameImpl *frame);
+    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;
+    virtual void doneOpenGLContextCurrent() override;
+    Decoration::Renderer *createDecorationRenderer(Decoration::DecoratedClientImpl \
*impl) override; +    virtual void triggerFence() override;
+    virtual QMatrix4x4 projectionMatrix() const = 0;
+    bool animationsSupported() const override;
+
+    void insertWait();
+
+    void idle();
+
+    bool debug() const { return m_debug; }
+    void initDebugOutput();
+
+    /**
+     * @brief Factory method to create a backend specific texture.
+     *
+     * @return :SceneOpenGL::Texture*
+     **/
+    SceneOpenGLTexture *createTexture();
+
+    OpenGLBackend *backend() const {
+        return m_backend;
+    }
+
+    QVector<QByteArray> openGLPlatformInterfaceExtensions() const override;
+
+    static SceneOpenGL *createScene(QObject *parent);
+
+protected:
+    SceneOpenGL(OpenGLBackend *backend, QObject *parent = nullptr);
+    virtual void paintBackground(QRegion region);
+    virtual void extendPaintRegion(QRegion &region, bool opaqueFullscreen);
+    QMatrix4x4 transformation(int mask, const ScreenPaintData &data) const;
+    virtual void paintDesktop(int desktop, int mask, const QRegion &region, \
ScreenPaintData &data); +
+    void handleGraphicsReset(GLenum status);
+
+    virtual void doPaintBackground(const QVector<float> &vertices) = 0;
+    virtual void updateProjectionMatrix() = 0;
+
+protected:
+    bool init_ok;
+private:
+    bool viewportLimitsMatched(const QSize &size) const;
+private:
+    bool m_debug;
+    OpenGLBackend *m_backend;
+    SyncManager *m_syncManager;
+    SyncObject *m_currentFence;
+};
+
+class SceneOpenGL2 : public SceneOpenGL
+{
+    Q_OBJECT
+public:
+    explicit SceneOpenGL2(OpenGLBackend *backend, QObject *parent = nullptr);
+    virtual ~SceneOpenGL2();
+    virtual CompositingType compositingType() const {
+        return OpenGL2Compositing;
+    }
+
+    static bool supported(OpenGLBackend *backend);
+
+    QMatrix4x4 projectionMatrix() const override { return m_projectionMatrix; }
+    QMatrix4x4 screenProjectionMatrix() const override { return \
m_screenProjectionMatrix; } +
+protected:
+    virtual void paintSimpleScreen(int mask, QRegion region);
+    virtual void paintGenericScreen(int mask, ScreenPaintData data);
+    virtual void doPaintBackground(const QVector< float >& vertices);
+    virtual Scene::Window *createWindow(Toplevel *t);
+    virtual void finalDrawWindow(EffectWindowImpl* w, int mask, QRegion region, \
WindowPaintData& data); +    virtual void updateProjectionMatrix() override;
+    void paintCursor() override;
+
+private:
+    void performPaintWindow(EffectWindowImpl* w, int mask, QRegion region, \
WindowPaintData& data); +    QMatrix4x4 createProjectionMatrix() const;
+
+private:
+    LanczosFilter *m_lanczosFilter;
+    QScopedPointer<GLTexture> m_cursorTexture;
+    QMatrix4x4 m_projectionMatrix;
+    QMatrix4x4 m_screenProjectionMatrix;
+    GLuint vao;
+};
+
+class SceneOpenGL::Window
+    : public Scene::Window
+{
+public:
+    virtual ~Window();
+    bool beginRenderWindow(int mask, const QRegion &region, WindowPaintData &data);
+    virtual void performPaint(int mask, QRegion region, WindowPaintData data) = 0;
+    void endRenderWindow();
+    bool bindTexture();
+    void setScene(SceneOpenGL *scene) {
+        m_scene = scene;
+    }
+
+protected:
+    virtual WindowPixmap* createWindowPixmap();
+    Window(Toplevel* c);
+    enum TextureType {
+        Content,
+        Decoration,
+        Shadow
+    };
+
+    QMatrix4x4 transformation(int mask, const WindowPaintData &data) const;
+    GLTexture *getDecorationTexture() const;
+
+protected:
+    SceneOpenGL *m_scene;
+    bool m_hardwareClipping;
+};
+
+class SceneOpenGL2Window : public SceneOpenGL::Window
+{
+public:
+    enum Leaf { ShadowLeaf = 0, DecorationLeaf, ContentLeaf, PreviousContentLeaf, \
LeafCount }; +
+    struct LeafNode
+    {
+        LeafNode()
+            : texture(0),
+              firstVertex(0),
+              vertexCount(0),
+              opacity(1.0),
+              hasAlpha(false),
+              coordinateType(UnnormalizedCoordinates)
+        {
+        }
+
+        GLTexture *texture;
+        int firstVertex;
+        int vertexCount;
+        float opacity;
+        bool hasAlpha;
+        TextureCoordinateType coordinateType;
+    };
+
+    explicit SceneOpenGL2Window(Toplevel *c);
+    virtual ~SceneOpenGL2Window();
+
+protected:
+    QMatrix4x4 modelViewProjectionMatrix(int mask, const WindowPaintData &data) \
const; +    QVector4D modulate(float opacity, float brightness) const;
+    void setBlendEnabled(bool enabled);
+    void setupLeafNodes(LeafNode *nodes, const WindowQuadList *quads, const \
WindowPaintData &data); +    virtual void performPaint(int mask, QRegion region, \
WindowPaintData data); +
+private:
+    /**
+     * Whether prepareStates enabled blending and restore states should disable \
again. +     **/
+    bool m_blendingEnabled;
+};
+
+class OpenGLWindowPixmap : public WindowPixmap
+{
+public:
+    explicit OpenGLWindowPixmap(Scene::Window *window, SceneOpenGL *scene);
+    virtual ~OpenGLWindowPixmap();
+    SceneOpenGLTexture *texture() const;
+    bool bind();
+    bool isValid() const override;
+protected:
+    WindowPixmap *createChild(const QPointer<KWayland::Server::SubSurfaceInterface> \
&subSurface) override; +private:
+    explicit OpenGLWindowPixmap(const \
QPointer<KWayland::Server::SubSurfaceInterface> &subSurface, WindowPixmap *parent, \
SceneOpenGL *scene); +    QScopedPointer<SceneOpenGLTexture> m_texture;
+    SceneOpenGL *m_scene;
+};
+
+class SceneOpenGL::EffectFrame
+    : public Scene::EffectFrame
+{
+public:
+    EffectFrame(EffectFrameImpl* frame, SceneOpenGL *scene);
+    virtual ~EffectFrame();
+
+    virtual void free();
+    virtual void freeIconFrame();
+    virtual void freeTextFrame();
+    virtual void freeSelection();
+
+    virtual void render(QRegion region, double opacity, double frameOpacity);
+
+    virtual void crossFadeIcon();
+    virtual void crossFadeText();
+
+    static void cleanup();
+
+private:
+    void updateTexture();
+    void updateTextTexture();
+
+    GLTexture *m_texture;
+    GLTexture *m_textTexture;
+    GLTexture *m_oldTextTexture;
+    QPixmap *m_textPixmap; // need to keep the pixmap around to workaround some \
driver problems +    GLTexture *m_iconTexture;
+    GLTexture *m_oldIconTexture;
+    GLTexture *m_selectionTexture;
+    GLVertexBuffer *m_unstyledVBO;
+    SceneOpenGL *m_scene;
+
+    static GLTexture* m_unstyledTexture;
+    static QPixmap* m_unstyledPixmap; // need to keep the pixmap around to \
workaround some driver problems +    static void updateUnstyledTexture(); // Update \
OpenGL unstyled frame texture +};
+
+/**
+ * @short OpenGL implementation of Shadow.
+ *
+ * This class extends Shadow by the Elements required for OpenGL rendering.
+ * @author Martin Gräßlin <mgraesslin@kde.org>
+ **/
+class SceneOpenGLShadow
+    : public Shadow
+{
+public:
+    explicit SceneOpenGLShadow(Toplevel *toplevel);
+    virtual ~SceneOpenGLShadow();
+
+    GLTexture *shadowTexture() {
+        return m_texture.data();
+    }
+protected:
+    virtual void buildQuads();
+    virtual bool prepareBackend();
+private:
+    QSharedPointer<GLTexture> m_texture;
+};
+
+class SceneOpenGLDecorationRenderer : public Decoration::Renderer
+{
+    Q_OBJECT
+public:
+    enum class DecorationPart : int {
+        Left,
+        Top,
+        Right,
+        Bottom,
+        Count
+    };
+    explicit SceneOpenGLDecorationRenderer(Decoration::DecoratedClientImpl *client);
+    virtual ~SceneOpenGLDecorationRenderer();
+
+    void render() override;
+    void reparent(Deleted *deleted) override;
+
+    GLTexture *texture() {
+        return m_texture.data();
+    }
+    GLTexture *texture() const {
+        return m_texture.data();
+    }
+
+private:
+    void resizeTexture();
+    QScopedPointer<GLTexture> m_texture;
+};
+
+inline bool SceneOpenGL::hasPendingFlush() const
+{
+    return m_backend->hasPendingFlush();
+}
+
+inline bool SceneOpenGL::usesOverlayWindow() const
+{
+    return m_backend->usesOverlayWindow();
+}
+
+inline SceneOpenGLTexture* OpenGLWindowPixmap::texture() const
+{
+    return m_texture.data();
+}
+
+class KWIN_EXPORT OpenGLFactory : public SceneFactory
+{
+    Q_OBJECT
+    Q_INTERFACES(KWin::SceneFactory)
+    Q_PLUGIN_METADATA(IID "org.kde.kwin.Scene" FILE "opengl.json")
+
+public:
+    explicit OpenGLFactory(QObject *parent = nullptr);
+    ~OpenGLFactory() override;
+
+    Scene *create(QObject *parent = nullptr) const override;
+};
+
+} // namespace
+
+#endif
diff --git a/scene.h b/scene.h
index d80217b95..8f3b9615f 100644
--- a/scene.h
+++ b/scene.h
@@ -186,6 +186,7 @@ public:
 
 Q_SIGNALS:
     void frameRendered();
+    void resetCompositing();
 
 public Q_SLOTS:
     // a window has been destroyed
diff --git a/scene_opengl.h b/scene_opengl.h
deleted file mode 100644
index be09697f5..000000000
--- a/scene_opengl.h
+++ /dev/null
@@ -1,694 +0,0 @@
-/********************************************************************
- KWin - the KDE window manager
- This file is part of the KDE project.
-
-Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
-Copyright (C) 2009, 2010, 2011 Martin Gräßlin <mgraesslin@kde.org>
-
-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 <http://www.gnu.org/licenses/>.
-*********************************************************************/
-
-#ifndef KWIN_SCENE_OPENGL_H
-#define KWIN_SCENE_OPENGL_H
-
-#include "scene.h"
-#include "shadow.h"
-
-#include "kwinglutils.h"
-#include "kwingltexture_p.h"
-
-#include "decorations/decorationrenderer.h"
-
-namespace KWin
-{
-class LanczosFilter;
-class OpenGLBackend;
-class SyncManager;
-class SyncObject;
-
-class KWIN_EXPORT SceneOpenGL
-    : public Scene
-{
-    Q_OBJECT
-public:
-    class EffectFrame;
-    class Texture;
-    class TexturePrivate;
-    class Window;
-    virtual ~SceneOpenGL();
-    virtual bool initFailed() const;
-    virtual bool hasPendingFlush() const;
-    virtual qint64 paint(QRegion damage, ToplevelList windows);
-    virtual Scene::EffectFrame *createEffectFrame(EffectFrameImpl *frame);
-    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;
-    virtual void doneOpenGLContextCurrent() override;
-    Decoration::Renderer *createDecorationRenderer(Decoration::DecoratedClientImpl \
                *impl) override;
-    virtual void triggerFence() override;
-    virtual QMatrix4x4 projectionMatrix() const = 0;
-    bool animationsSupported() const override;
-
-    void insertWait();
-
-    void idle();
-
-    bool debug() const { return m_debug; }
-    void initDebugOutput();
-
-    /**
-     * @brief Factory method to create a backend specific texture.
-     *
-     * @return :SceneOpenGL::Texture*
-     **/
-    Texture *createTexture();
-
-    OpenGLBackend *backend() const {
-        return m_backend;
-    }
-
-    QVector<QByteArray> openGLPlatformInterfaceExtensions() const override;
-
-    /**
-     * Copy a region of pixels from the current read to the current draw buffer
-     */
-    static void copyPixels(const QRegion &region);
-
-    static SceneOpenGL *createScene(QObject *parent);
-
-protected:
-    SceneOpenGL(OpenGLBackend *backend, QObject *parent = nullptr);
-    virtual void paintBackground(QRegion region);
-    virtual void extendPaintRegion(QRegion &region, bool opaqueFullscreen);
-    QMatrix4x4 transformation(int mask, const ScreenPaintData &data) const;
-    virtual void paintDesktop(int desktop, int mask, const QRegion &region, \
                ScreenPaintData &data);
-
-    void handleGraphicsReset(GLenum status);
-
-    virtual void doPaintBackground(const QVector<float> &vertices) = 0;
-    virtual void updateProjectionMatrix() = 0;
-
-Q_SIGNALS:
-    void resetCompositing();
-
-protected:
-    bool init_ok;
-private:
-    bool viewportLimitsMatched(const QSize &size) const;
-private:
-    bool m_debug;
-    OpenGLBackend *m_backend;
-    SyncManager *m_syncManager;
-    SyncObject *m_currentFence;
-};
-
-class SceneOpenGL2 : public SceneOpenGL
-{
-    Q_OBJECT
-public:
-    explicit SceneOpenGL2(OpenGLBackend *backend, QObject *parent = nullptr);
-    virtual ~SceneOpenGL2();
-    virtual CompositingType compositingType() const {
-        return OpenGL2Compositing;
-    }
-
-    static bool supported(OpenGLBackend *backend);
-
-    QMatrix4x4 projectionMatrix() const override { return m_projectionMatrix; }
-    QMatrix4x4 screenProjectionMatrix() const override { return \
                m_screenProjectionMatrix; }
-
-protected:
-    virtual void paintSimpleScreen(int mask, QRegion region);
-    virtual void paintGenericScreen(int mask, ScreenPaintData data);
-    virtual void doPaintBackground(const QVector< float >& vertices);
-    virtual Scene::Window *createWindow(Toplevel *t);
-    virtual void finalDrawWindow(EffectWindowImpl* w, int mask, QRegion region, \
                WindowPaintData& data);
-    virtual void updateProjectionMatrix() override;
-    void paintCursor() override;
-
-private:
-    void performPaintWindow(EffectWindowImpl* w, int mask, QRegion region, \
                WindowPaintData& data);
-    QMatrix4x4 createProjectionMatrix() const;
-
-private:
-    LanczosFilter *m_lanczosFilter;
-    QScopedPointer<GLTexture> m_cursorTexture;
-    QMatrix4x4 m_projectionMatrix;
-    QMatrix4x4 m_screenProjectionMatrix;
-    GLuint vao;
-};
-
-class SceneOpenGL::TexturePrivate
-    : public GLTexturePrivate
-{
-public:
-    virtual ~TexturePrivate();
-
-    virtual bool loadTexture(WindowPixmap *pixmap) = 0;
-    virtual void updateTexture(WindowPixmap *pixmap);
-    virtual OpenGLBackend *backend() = 0;
-
-protected:
-    TexturePrivate();
-
-private:
-    Q_DISABLE_COPY(TexturePrivate)
-};
-
-class SceneOpenGL::Texture
-    : public GLTexture
-{
-public:
-    Texture(OpenGLBackend *backend);
-    virtual ~Texture();
-
-    Texture & operator = (const Texture& tex);
-
-    void discard() override final;
-
-protected:
-    bool load(WindowPixmap *pixmap);
-    void updateFromPixmap(WindowPixmap *pixmap);
-
-    Texture(TexturePrivate& dd);
-
-private:
-    Q_DECLARE_PRIVATE(Texture)
-
-    friend class OpenGLWindowPixmap;
-};
-
-class SceneOpenGL::Window
-    : public Scene::Window
-{
-public:
-    virtual ~Window();
-    bool beginRenderWindow(int mask, const QRegion &region, WindowPaintData &data);
-    virtual void performPaint(int mask, QRegion region, WindowPaintData data) = 0;
-    void endRenderWindow();
-    bool bindTexture();
-    void setScene(SceneOpenGL *scene) {
-        m_scene = scene;
-    }
-
-protected:
-    virtual WindowPixmap* createWindowPixmap();
-    Window(Toplevel* c);
-    enum TextureType {
-        Content,
-        Decoration,
-        Shadow
-    };
-
-    QMatrix4x4 transformation(int mask, const WindowPaintData &data) const;
-    GLTexture *getDecorationTexture() const;
-
-protected:
-    SceneOpenGL *m_scene;
-    bool m_hardwareClipping;
-};
-
-class SceneOpenGL2Window : public SceneOpenGL::Window
-{
-public:
-    enum Leaf { ShadowLeaf = 0, DecorationLeaf, ContentLeaf, PreviousContentLeaf, \
                LeafCount };
-
-    struct LeafNode
-    {
-        LeafNode()
-            : texture(0),
-              firstVertex(0),
-              vertexCount(0),
-              opacity(1.0),
-              hasAlpha(false),
-              coordinateType(UnnormalizedCoordinates)
-        {
-        }
-
-        GLTexture *texture;
-        int firstVertex;
-        int vertexCount;
-        float opacity;
-        bool hasAlpha;
-        TextureCoordinateType coordinateType;
-    };
-
-    explicit SceneOpenGL2Window(Toplevel *c);
-    virtual ~SceneOpenGL2Window();
-
-protected:
-    QMatrix4x4 modelViewProjectionMatrix(int mask, const WindowPaintData &data) \
                const;
-    QVector4D modulate(float opacity, float brightness) const;
-    void setBlendEnabled(bool enabled);
-    void setupLeafNodes(LeafNode *nodes, const WindowQuadList *quads, const \
                WindowPaintData &data);
-    virtual void performPaint(int mask, QRegion region, WindowPaintData data);
-
-private:
-    /**
-     * Whether prepareStates enabled blending and restore states should disable \
                again.
-     **/
-    bool m_blendingEnabled;
-};
-
-class OpenGLWindowPixmap : public WindowPixmap
-{
-public:
-    explicit OpenGLWindowPixmap(Scene::Window *window, SceneOpenGL *scene);
-    virtual ~OpenGLWindowPixmap();
-    SceneOpenGL::Texture *texture() const;
-    bool bind();
-    bool isValid() const override;
-protected:
-    WindowPixmap *createChild(const QPointer<KWayland::Server::SubSurfaceInterface> \
                &subSurface) override;
-private:
-    explicit OpenGLWindowPixmap(const \
QPointer<KWayland::Server::SubSurfaceInterface> &subSurface, WindowPixmap *parent, \
                SceneOpenGL *scene);
-    QScopedPointer<SceneOpenGL::Texture> m_texture;
-    SceneOpenGL *m_scene;
-};
-
-class SceneOpenGL::EffectFrame
-    : public Scene::EffectFrame
-{
-public:
-    EffectFrame(EffectFrameImpl* frame, SceneOpenGL *scene);
-    virtual ~EffectFrame();
-
-    virtual void free();
-    virtual void freeIconFrame();
-    virtual void freeTextFrame();
-    virtual void freeSelection();
-
-    virtual void render(QRegion region, double opacity, double frameOpacity);
-
-    virtual void crossFadeIcon();
-    virtual void crossFadeText();
-
-    static void cleanup();
-
-private:
-    void updateTexture();
-    void updateTextTexture();
-
-    GLTexture *m_texture;
-    GLTexture *m_textTexture;
-    GLTexture *m_oldTextTexture;
-    QPixmap *m_textPixmap; // need to keep the pixmap around to workaround some \
                driver problems
-    GLTexture *m_iconTexture;
-    GLTexture *m_oldIconTexture;
-    GLTexture *m_selectionTexture;
-    GLVertexBuffer *m_unstyledVBO;
-    SceneOpenGL *m_scene;
-
-    static GLTexture* m_unstyledTexture;
-    static QPixmap* m_unstyledPixmap; // need to keep the pixmap around to \
                workaround some driver problems
-    static void updateUnstyledTexture(); // Update OpenGL unstyled frame texture
-};
-
-/**
- * @short OpenGL implementation of Shadow.
- *
- * This class extends Shadow by the Elements required for OpenGL rendering.
- * @author Martin Gräßlin <mgraesslin@kde.org>
- **/
-class SceneOpenGLShadow
-    : public Shadow
-{
-public:
-    explicit SceneOpenGLShadow(Toplevel *toplevel);
-    virtual ~SceneOpenGLShadow();
-
-    GLTexture *shadowTexture() {
-        return m_texture.data();
-    }
-protected:
-    virtual void buildQuads();
-    virtual bool prepareBackend();
-private:
-    QSharedPointer<GLTexture> m_texture;
-};
-
-/**
- * @short Profiler to detect whether we have triple buffering
- * The strategy is to start setBlocksForRetrace(false) but assume blocking and have \
                the system prove that assumption wrong
- **/
-class KWIN_EXPORT SwapProfiler
-{
-public:
-    SwapProfiler();
-    void init();
-    void begin();
-    /**
-     * @return char being 'd' for double, 't' for triple (or more - but \
                non-blocking) buffering and
-     * 0 (NOT '0') otherwise, so you can act on "if (char result = \
                SwapProfiler::end()) { fooBar(); }
-     **/
-    char end();
-private:
-    QElapsedTimer m_timer;
-    qint64  m_time;
-    int m_counter;
-};
-
-/**
- * @brief The OpenGLBackend creates and holds the OpenGL context and is responsible \
                for Texture from Pixmap.
- *
- * The OpenGLBackend is an abstract base class used by the SceneOpenGL to abstract \
                away the differences
- * between various OpenGL windowing systems such as GLX and EGL.
- *
- * A concrete implementation has to create and release the OpenGL context in a way \
                so that the
- * SceneOpenGL does not have to care about it.
- *
- * In addition a major task for this class is to generate the \
                SceneOpenGL::TexturePrivate which is
- * able to perform the texture from pixmap operation in the given backend.
- *
- * @author Martin Gräßlin <mgraesslin@kde.org>
- **/
-class KWIN_EXPORT OpenGLBackend
-{
-public:
-    OpenGLBackend();
-    virtual ~OpenGLBackend();
-
-    virtual void init() = 0;
-    /**
-     * @return Time passes since start of rendering current frame.
-     * @see startRenderTimer
-     **/
-    qint64 renderTime() {
-        return m_renderTimer.nsecsElapsed();
-    }
-    virtual void screenGeometryChanged(const QSize &size) = 0;
-    virtual SceneOpenGL::TexturePrivate *createBackendTexture(SceneOpenGL::Texture \
                *texture) = 0;
-
-    /**
-     * @brief Backend specific code to prepare the rendering of a frame including \
                flushing the
-     * previously rendered frame to the screen if the backend works this way.
-     *
-     * @return A region that if not empty will be repainted in addition to the \
                damaged region
-     **/
-    virtual QRegion prepareRenderingFrame() = 0;
-
-    /**
-     * @brief Backend specific code to handle the end of rendering a frame.
-     *
-     * @param renderedRegion The possibly larger region that has been rendered
-     * @param damagedRegion The damaged region that should be posted
-     **/
-    virtual void endRenderingFrame(const QRegion &damage, const QRegion \
                &damagedRegion) = 0;
-    virtual void endRenderingFrameForScreen(int screenId, const QRegion &damage, \
                const QRegion &damagedRegion);
-    virtual bool makeCurrent() = 0;
-    virtual void doneCurrent() = 0;
-    virtual bool usesOverlayWindow() const = 0;
-    /**
-     * Whether the rendering needs to be split per screen.
-     * Default implementation returns @c false.
-     **/
-    virtual bool perScreenRendering() const;
-    virtual QRegion prepareRenderingForScreen(int screenId);
-    /**
-     * @brief Compositor is going into idle mode, flushes any pending paints.
-     **/
-    void idle();
-
-    /**
-     * @return bool Whether the scene needs to flush a frame.
-     **/
-    bool hasPendingFlush() const {
-        return !m_lastDamage.isEmpty();
-    }
-
-    /**
-     * @brief Returns the OverlayWindow used by the backend.
-     *
-     * A backend does not have to use an OverlayWindow, this is mostly for the X \
                world.
-     * In case the backend does not use an OverlayWindow it is allowed to return @c \
                null.
-     * It's the task of the caller to check whether it is @c null.
-     *
-     * @return :OverlayWindow*
-     **/
-    virtual OverlayWindow *overlayWindow();
-    /**
-     * @brief Whether the creation of the Backend failed.
-     *
-     * The SceneOpenGL should test whether the Backend got constructed correctly. If \
                this method
-     * returns @c true, the SceneOpenGL should not try to start the rendering.
-     *
-     * @return bool @c true if the creation of the Backend failed, @c false \
                otherwise.
-     **/
-    bool isFailed() const {
-        return m_failed;
-    }
-    /**
-     * @brief Whether the Backend provides VSync.
-     *
-     * Currently only the GLX backend can provide VSync.
-     *
-     * @return bool @c true if VSync support is available, @c false otherwise
-     **/
-    bool syncsToVBlank() const {
-        return m_syncsToVBlank;
-    }
-    /**
-     * @brief Whether VSync blocks execution until the screen is in the retrace
-     *
-     * Case for waitVideoSync and non triple buffering buffer swaps
-     *
-     **/
-    bool blocksForRetrace() const {
-        return m_blocksForRetrace;
-    }
-    /**
-     * @brief Whether the backend uses direct rendering.
-     *
-     * Some OpenGLScene modes require direct rendering. E.g. the OpenGL 2 should not \
                be used
-     * if direct rendering is not supported by the Scene.
-     *
-     * @return bool @c true if the GL context is direct, @c false if indirect
-     **/
-    bool isDirectRendering() const {
-        return m_directRendering;
-    }
-
-    bool supportsBufferAge() const {
-        return m_haveBufferAge;
-    }
-
-    /**
-     * @returns whether the context is surfaceless
-     **/
-    bool isSurfaceLessContext() const {
-        return m_surfaceLessContext;
-    }
-
-    /**
-     * Returns the damage that has accumulated since a buffer of the given age was \
                presented.
-     */
-    QRegion accumulatedDamageHistory(int bufferAge) const;
-
-    /**
-     * Saves the given region to damage history.
-     */
-    void addToDamageHistory(const QRegion &region);
-
-    /**
-     * The backend specific extensions (e.g. EGL/GLX extensions).
-     *
-     * Not the OpenGL (ES) extension!
-     **/
-    QList<QByteArray> extensions() const {
-        return m_extensions;
-    }
-
-    /**
-     * @returns whether the backend specific extensions contains @p extension.
-     **/
-    bool hasExtension(const QByteArray &extension) const {
-        return m_extensions.contains(extension);
-    }
-
-protected:
-    /**
-     * @brief Backend specific flushing of frame to screen.
-     **/
-    virtual void present() = 0;
-    /**
-     * @brief Sets the backend initialization to failed.
-     *
-     * This method should be called by the concrete subclass in case the \
                initialization failed.
-     * The given @p reason is logged as a warning.
-     *
-     * @param reason The reason why the initialization failed.
-     **/
-    void setFailed(const QString &reason);
-    /**
-     * @brief Sets whether the backend provides VSync.
-     *
-     * Should be called by the concrete subclass once it is determined whether VSync \
                is supported.
-     * If the subclass does not call this method, the backend defaults to @c false.
-     * @param enabled @c true if VSync support available, @c false otherwise.
-     **/
-    void setSyncsToVBlank(bool enabled) {
-        m_syncsToVBlank = enabled;
-    }
-    /**
-     * @brief Sets whether the VSync iplementation blocks
-     *
-     * Should be called by the concrete subclass once it is determined how VSync \
                works.
-     * If the subclass does not call this method, the backend defaults to @c false.
-     * @param enabled @c true if VSync blocks, @c false otherwise.
-     **/
-    void setBlocksForRetrace(bool enabled) {
-        m_blocksForRetrace = enabled;
-    }
-    /**
-     * @brief Sets whether the OpenGL context is direct.
-     *
-     * Should be called by the concrete subclass once it is determined whether the \
                OpenGL context is
-     * direct or indirect.
-     * If the subclass does not call this method, the backend defaults to @c false.
-     *
-     * @param direct @c true if the OpenGL context is direct, @c false if indirect
-     **/
-    void setIsDirectRendering(bool direct) {
-        m_directRendering = direct;
-    }
-
-    void setSupportsBufferAge(bool value) {
-        m_haveBufferAge = value;
-    }
-
-    /**
-     * @return const QRegion& Damage of previously rendered frame
-     **/
-    const QRegion &lastDamage() const {
-        return m_lastDamage;
-    }
-    void setLastDamage(const QRegion &damage) {
-        m_lastDamage = damage;
-    }
-    /**
-     * @brief Starts the timer for how long it takes to render the frame.
-     *
-     * @see renderTime
-     **/
-    void startRenderTimer() {
-        m_renderTimer.start();
-    }
-
-    /**
-     * @param set whether the context is surface less
-     **/
-    void setSurfaceLessContext(bool set) {
-        m_surfaceLessContext = set;
-    }
-
-    /**
-     * Sets the platform-specific @p extensions.
-     *
-     * These are the EGL/GLX extensions, not the OpenGL extensions
-     **/
-    void setExtensions(const QList<QByteArray> &extensions) {
-        m_extensions = extensions;
-    }
-
-    SwapProfiler m_swapProfiler;
-
-private:
-    /**
-     * @brief Whether VSync is available and used, defaults to @c false.
-     **/
-    bool m_syncsToVBlank;
-    /**
-     * @brief Whether present() will block execution until the next vertical retrace \
                @c false.
-     **/
-    bool m_blocksForRetrace;
-    /**
-     * @brief Whether direct rendering is used, defaults to @c false.
-     **/
-    bool m_directRendering;
-    /**
-     * @brief Whether the backend supports GLX_EXT_buffer_age / EGL_EXT_buffer_age.
-     */
-    bool m_haveBufferAge;
-    /**
-     * @brief Whether the initialization failed, of course default to @c false.
-     **/
-    bool m_failed;
-    /**
-     * @brief Damaged region of previously rendered frame.
-     **/
-    QRegion m_lastDamage;
-    /**
-     * @brief The damage history for the past 10 frames.
-     */
-    QList<QRegion> m_damageHistory;
-    /**
-     * @brief Timer to measure how long a frame renders.
-     **/
-    QElapsedTimer m_renderTimer;
-    bool m_surfaceLessContext = false;
-
-    QList<QByteArray> m_extensions;
-};
-
-class SceneOpenGLDecorationRenderer : public Decoration::Renderer
-{
-    Q_OBJECT
-public:
-    enum class DecorationPart : int {
-        Left,
-        Top,
-        Right,
-        Bottom,
-        Count
-    };
-    explicit SceneOpenGLDecorationRenderer(Decoration::DecoratedClientImpl *client);
-    virtual ~SceneOpenGLDecorationRenderer();
-
-    void render() override;
-    void reparent(Deleted *deleted) override;
-
-    GLTexture *texture() {
-        return m_texture.data();
-    }
-    GLTexture *texture() const {
-        return m_texture.data();
-    }
-
-private:
-    void resizeTexture();
-    QScopedPointer<GLTexture> m_texture;
-};
-
-inline bool SceneOpenGL::hasPendingFlush() const
-{
-    return m_backend->hasPendingFlush();
-}
-
-inline bool SceneOpenGL::usesOverlayWindow() const
-{
-    return m_backend->usesOverlayWindow();
-}
-
-inline SceneOpenGL::Texture* OpenGLWindowPixmap::texture() const
-{
-    return m_texture.data();
-}
-
-} // namespace
-
-#endif


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic