summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/platformsupport/eglconvenience/eglconvenience.pri4
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformintegration.cpp9
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformscreen.cpp49
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformscreen_p.h13
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformwindow.cpp22
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformwindow_p.h17
-rw-r--r--src/platformsupport/platformcompositor/platformcompositor.pri7
-rw-r--r--src/platformsupport/platformcompositor/qopenglcompositor.cpp (renamed from src/platformsupport/eglconvenience/qeglcompositor.cpp)158
-rw-r--r--src/platformsupport/platformcompositor/qopenglcompositor_p.h (renamed from src/platformsupport/eglconvenience/qeglcompositor_p.h)52
-rw-r--r--src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp (renamed from src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp)103
-rw-r--r--src/platformsupport/platformcompositor/qopenglcompositorbackingstore_p.h (renamed from src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h)20
-rw-r--r--src/platformsupport/platformsupport.pro1
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp4
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h8
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.cpp35
15 files changed, 262 insertions, 240 deletions
diff --git a/src/platformsupport/eglconvenience/eglconvenience.pri b/src/platformsupport/eglconvenience/eglconvenience.pri
index 8ada53d2c1..d102203d5e 100644
--- a/src/platformsupport/eglconvenience/eglconvenience.pri
+++ b/src/platformsupport/eglconvenience/eglconvenience.pri
@@ -16,16 +16,12 @@ contains(QT_CONFIG,egl) {
$$PWD/qeglplatformcursor_p.h \
$$PWD/qeglplatformwindow_p.h \
$$PWD/qeglplatformscreen_p.h \
- $$PWD/qeglcompositor_p.h \
- $$PWD/qeglplatformbackingstore_p.h \
$$PWD/qeglplatformintegration_p.h
SOURCES += \
$$PWD/qeglplatformcursor.cpp \
$$PWD/qeglplatformwindow.cpp \
$$PWD/qeglplatformscreen.cpp \
- $$PWD/qeglcompositor.cpp \
- $$PWD/qeglplatformbackingstore.cpp \
$$PWD/qeglplatformintegration.cpp
}
}
diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp
index fea2ae2369..09011e6e58 100644
--- a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp
@@ -43,6 +43,7 @@
#include <QtPlatformSupport/private/qgenericunixservices_p.h>
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
#include <QtPlatformSupport/private/qfbvthandler_p.h>
+#include <QtPlatformSupport/private/qopenglcompositorbackingstore_p.h>
#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
@@ -59,7 +60,6 @@
#include "qeglplatformintegration_p.h"
#include "qeglplatformcontext_p.h"
#include "qeglplatformwindow_p.h"
-#include "qeglplatformbackingstore_p.h"
#include "qeglplatformscreen_p.h"
#include "qeglplatformcursor_p.h"
@@ -141,7 +141,9 @@ QPlatformFontDatabase *QEGLPlatformIntegration::fontDatabase() const
QPlatformBackingStore *QEGLPlatformIntegration::createPlatformBackingStore(QWindow *window) const
{
- return new QEGLPlatformBackingStore(window);
+ QOpenGLCompositorBackingStore *bs = new QOpenGLCompositorBackingStore(window);
+ static_cast<QEGLPlatformWindow *>(window->handle())->setBackingStore(bs);
+ return bs;
}
QPlatformWindow *QEGLPlatformIntegration::createPlatformWindow(QWindow *window) const
@@ -156,10 +158,9 @@ QPlatformWindow *QEGLPlatformIntegration::createPlatformWindow(QWindow *window)
QPlatformOpenGLContext *QEGLPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(context->screen()->handle());
// If there is a "root" window into which raster and QOpenGLWidget content is
// composited, all other contexts must share with its context.
- QOpenGLContext *compositingContext = screen ? screen->compositingContext() : 0;
+ QOpenGLContext *compositingContext = QOpenGLCompositor::instance()->context();
QPlatformOpenGLContext *share = compositingContext ? compositingContext->handle() : context->shareHandle();
QVariant nativeHandle = context->nativeHandle();
QPlatformOpenGLContext *platformContext = createContext(context->format(),
diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp
index fd577a48d7..fd9befb575 100644
--- a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp
@@ -31,8 +31,8 @@
**
****************************************************************************/
-#include "qeglcompositor_p.h"
#include "qeglplatformscreen_p.h"
+#include <QtPlatformSupport/private/qopenglcompositor_p.h>
QT_BEGIN_NAMESPACE
@@ -42,19 +42,6 @@ QT_BEGIN_NAMESPACE
\since 5.2
\internal
\ingroup qpa
-
- This class provides a lightweight base for QPlatformScreen
- implementations. It covers basic window stack management which is
- necessary when compositing multiple raster (widget-based) windows
- together into one single native surface.
-
- Reimplementing the virtuals are essential when using
- QEGLPlatformBackingStore. The context and the window returned from
- these are the ones that are used when compositing the textures
- generated from the raster (widget) based windows.
-
- \note It is up to the QEGLPlatformWindow subclasses to use the
- functions, like addWindow(), removeWindow(), etc., provided here.
*/
QEGLPlatformScreen::QEGLPlatformScreen(EGLDisplay dpy)
@@ -64,39 +51,7 @@ QEGLPlatformScreen::QEGLPlatformScreen(EGLDisplay dpy)
QEGLPlatformScreen::~QEGLPlatformScreen()
{
- QEGLCompositor::destroy();
-}
-
-void QEGLPlatformScreen::addWindow(QEGLPlatformWindow *window)
-{
- if (!m_windows.contains(window)) {
- m_windows.append(window);
- topWindowChanged(window);
- }
-}
-
-void QEGLPlatformScreen::removeWindow(QEGLPlatformWindow *window)
-{
- m_windows.removeOne(window);
- if (!m_windows.isEmpty())
- topWindowChanged(m_windows.last());
-}
-
-void QEGLPlatformScreen::moveToTop(QEGLPlatformWindow *window)
-{
- m_windows.removeOne(window);
- m_windows.append(window);
- topWindowChanged(window);
-}
-
-void QEGLPlatformScreen::changeWindowIndex(QEGLPlatformWindow *window, int newIdx)
-{
- int idx = m_windows.indexOf(window);
- if (idx != -1 && idx != newIdx) {
- m_windows.move(idx, newIdx);
- if (newIdx == m_windows.size() - 1)
- topWindowChanged(m_windows.last());
- }
+ QOpenGLCompositor::destroy();
}
QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h b/src/platformsupport/eglconvenience/qeglplatformscreen_p.h
index bb1d26d7d2..e9d3363a66 100644
--- a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h
+++ b/src/platformsupport/eglconvenience/qeglplatformscreen_p.h
@@ -60,22 +60,9 @@ public:
QEGLPlatformScreen(EGLDisplay dpy);
~QEGLPlatformScreen();
- QList<QEGLPlatformWindow *> windows() const { return m_windows; }
-
- void addWindow(QEGLPlatformWindow *window);
- void removeWindow(QEGLPlatformWindow *window);
- void moveToTop(QEGLPlatformWindow *window);
- void changeWindowIndex(QEGLPlatformWindow *window, int newIdx);
-
- virtual void topWindowChanged(QEGLPlatformWindow *window) { Q_UNUSED(window); }
-
EGLDisplay display() const { return m_dpy; }
- virtual QEGLPlatformWindow *compositingWindow() = 0;
- virtual QOpenGLContext *compositingContext() = 0;
-
private:
- QList<QEGLPlatformWindow *> m_windows;
EGLDisplay m_dpy;
};
diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow.cpp b/src/platformsupport/eglconvenience/qeglplatformwindow.cpp
index af4c907e85..5e5c879a22 100644
--- a/src/platformsupport/eglconvenience/qeglplatformwindow.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformwindow.cpp
@@ -32,9 +32,10 @@
****************************************************************************/
#include <qpa/qwindowsysteminterface.h>
+#include <QtPlatformSupport/private/qopenglcompositor_p.h>
+#include <QtPlatformSupport/private/qopenglcompositorbackingstore_p.h>
#include "qeglplatformwindow_p.h"
-#include "qeglplatformbackingstore_p.h"
#include "qeglplatformscreen_p.h"
QT_BEGIN_NAMESPACE
@@ -47,7 +48,7 @@ QT_BEGIN_NAMESPACE
\ingroup qpa
Lightweight class providing some basic platform window operations
- and interfacing with QEGLPlatformBackingStore.
+ and interfacing with QOpenGLCompositorBackingStore.
Almost no QPlatformWindow functions are implemented here. This is
intentional because different platform plugins may use different
@@ -57,13 +58,15 @@ QT_BEGIN_NAMESPACE
enforce anything for these functions.
\note Subclasses are responsible for invoking this class'
- implementation of create(). When using QEGLPlatformScreen, the
- subclasses of this class are expected to utilize the window stack
- management functions (addWindow() etc.) provided there.
+ implementation of create() and are expected to utilize the window
+ stack management functions (addWindow() etc.) in
+ QOpenGLCompositor.
*/
QEGLPlatformWindow::QEGLPlatformWindow(QWindow *w)
: QPlatformWindow(w),
+ m_backingStore(0),
+ m_raster(false),
m_winId(0)
{
}
@@ -100,6 +103,11 @@ bool QEGLPlatformWindow::isRaster() const
return m_raster || window()->surfaceType() == QSurface::RasterGLSurface;
}
+QWindow *QEGLPlatformWindow::sourceWindow() const
+{
+ return window();
+}
+
const QPlatformTextureList *QEGLPlatformWindow::textures() const
{
if (m_backingStore)
@@ -108,10 +116,10 @@ const QPlatformTextureList *QEGLPlatformWindow::textures() const
return 0;
}
-void QEGLPlatformWindow::composited()
+void QEGLPlatformWindow::endCompositing()
{
if (m_backingStore)
- m_backingStore->composited();
+ m_backingStore->notifyComposited();
}
WId QEGLPlatformWindow::winId() const
diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow_p.h b/src/platformsupport/eglconvenience/qeglplatformwindow_p.h
index 3a19301e5d..947f02aeb5 100644
--- a/src/platformsupport/eglconvenience/qeglplatformwindow_p.h
+++ b/src/platformsupport/eglconvenience/qeglplatformwindow_p.h
@@ -46,33 +46,36 @@
//
#include <qpa/qplatformwindow.h>
+#include <QtPlatformSupport/private/qopenglcompositor_p.h>
#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
-class QEGLPlatformBackingStore;
+class QOpenGLCompositorBackingStore;
class QPlatformTextureList;
-class QEGLPlatformWindow : public QPlatformWindow
+class QEGLPlatformWindow : public QPlatformWindow, public QOpenGLCompositorWindow
{
public:
QEGLPlatformWindow(QWindow *w);
virtual void create();
- QEGLPlatformBackingStore *backingStore() { return m_backingStore; }
- void setBackingStore(QEGLPlatformBackingStore *backingStore) { m_backingStore = backingStore; }
- const QPlatformTextureList *textures() const;
- void composited();
+ QOpenGLCompositorBackingStore *backingStore() { return m_backingStore; }
+ void setBackingStore(QOpenGLCompositorBackingStore *backingStore) { m_backingStore = backingStore; }
bool isRaster() const;
+ QWindow *sourceWindow() const Q_DECL_OVERRIDE;
+ const QPlatformTextureList *textures() const Q_DECL_OVERRIDE;
+ void endCompositing() Q_DECL_OVERRIDE;
+
WId winId() const Q_DECL_OVERRIDE;
void setOpacity(qreal opacity) Q_DECL_OVERRIDE;
virtual EGLNativeWindowType eglWindow() const = 0;
private:
- QEGLPlatformBackingStore *m_backingStore;
+ QOpenGLCompositorBackingStore *m_backingStore;
bool m_raster;
WId m_winId;
};
diff --git a/src/platformsupport/platformcompositor/platformcompositor.pri b/src/platformsupport/platformcompositor/platformcompositor.pri
new file mode 100644
index 0000000000..923d7225da
--- /dev/null
+++ b/src/platformsupport/platformcompositor/platformcompositor.pri
@@ -0,0 +1,7 @@
+contains(QT_CONFIG, opengl) {
+ SOURCES += $$PWD/qopenglcompositor.cpp \
+ $$PWD/qopenglcompositorbackingstore.cpp
+
+ HEADERS += $$PWD/qopenglcompositor_p.h \
+ $$PWD/qopenglcompositorbackingstore_p.h
+}
diff --git a/src/platformsupport/eglconvenience/qeglcompositor.cpp b/src/platformsupport/platformcompositor/qopenglcompositor.cpp
index 5866edc48d..3fefdc4935 100644
--- a/src/platformsupport/eglconvenience/qeglcompositor.cpp
+++ b/src/platformsupport/platformcompositor/qopenglcompositor.cpp
@@ -32,23 +32,46 @@
****************************************************************************/
#include <QtGui/QOpenGLContext>
-#include <QtGui/QOpenGLShaderProgram>
-#include <QtGui/QOpenGLFramebufferObject>
-#include <QtGui/private/qopengltextureblitter_p.h>
+#include <QtGui/QWindow>
+#include <QtGui/QMatrix4x4>
#include <qpa/qplatformbackingstore.h>
-#include "qeglcompositor_p.h"
-#include "qeglplatformwindow_p.h"
-#include "qeglplatformscreen_p.h"
+#include "qopenglcompositor_p.h"
QT_BEGIN_NAMESPACE
-static QEGLCompositor *compositor = 0;
+/*!
+ \class QOpenGLCompositor
+ \brief A generic OpenGL-based compositor
+ \since 5.4
+ \internal
+ \ingroup qpa
-QEGLCompositor::QEGLCompositor()
+ This class provides a lightweight compositor that maintains the
+ basic stacking order of windows and composites them by drawing
+ textured quads via OpenGL.
+
+ It it meant to be used by platform plugins that run without a
+ windowing system.
+
+ It is up to the platform plugin to manage the lifetime of the
+ compositor (instance(), destroy()), set the correct destination
+ context and window as early as possible (setTargetWindow()),
+ register the composited windows as they are shown, activated,
+ raised and lowered (addWindow(), moveToTop(), etc.), and to
+ schedule repaints (update()).
+
+ \note To get support for QWidget-based windows, just use
+ QOpenGLCompositorBackingStore. It will automatically create
+ textures from the raster-rendered content and trigger the
+ necessary repaints.
+ */
+
+static QOpenGLCompositor *compositor = 0;
+
+QOpenGLCompositor::QOpenGLCompositor()
: m_context(0),
- m_window(0),
- m_blitter(0)
+ m_targetWindow(0)
{
Q_ASSERT(!compositor);
m_updateTimer.setSingleShot(true);
@@ -56,45 +79,51 @@ QEGLCompositor::QEGLCompositor()
connect(&m_updateTimer, SIGNAL(timeout()), SLOT(renderAll()));
}
-QEGLCompositor::~QEGLCompositor()
+QOpenGLCompositor::~QOpenGLCompositor()
{
Q_ASSERT(compositor == this);
- if (m_blitter) {
- m_blitter->destroy();
- delete m_blitter;
- }
+ m_blitter.destroy();
compositor = 0;
}
-void QEGLCompositor::schedule(QOpenGLContext *context, QEGLPlatformWindow *window)
+void QOpenGLCompositor::setTarget(QOpenGLContext *context, QWindow *targetWindow)
{
m_context = context;
- m_window = window;
+ m_targetWindow = targetWindow;
+}
+
+void QOpenGLCompositor::update()
+{
if (!m_updateTimer.isActive())
m_updateTimer.start();
}
-void QEGLCompositor::renderAll()
+void QOpenGLCompositor::renderAll()
{
- Q_ASSERT(m_context && m_window);
- m_context->makeCurrent(m_window->window());
+ Q_ASSERT(m_context && m_targetWindow);
+ m_context->makeCurrent(m_targetWindow);
- if (!m_blitter) {
- m_blitter = new QOpenGLTextureBlitter;
- m_blitter->create();
- }
- m_blitter->bind();
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ const QRect targetWindowRect(QPoint(0, 0), m_targetWindow->geometry().size());
+ glViewport(0, 0, targetWindowRect.width(), targetWindowRect.height());
- QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
- QList<QEGLPlatformWindow *> windows = screen->windows();
- for (int i = 0; i < windows.size(); ++i)
- render(windows.at(i));
+ if (!m_blitter.isCreated())
+ m_blitter.create();
- m_blitter->release();
- m_context->swapBuffers(m_window->window());
+ m_blitter.bind();
- for (int i = 0; i < windows.size(); ++i)
- windows.at(i)->composited();
+ for (int i = 0; i < m_windows.size(); ++i)
+ m_windows.at(i)->beginCompositing();
+
+ for (int i = 0; i < m_windows.size(); ++i)
+ render(m_windows.at(i));
+
+ m_blitter.release();
+ m_context->swapBuffers(m_targetWindow);
+
+ for (int i = 0; i < m_windows.size(); ++i)
+ m_windows.at(i)->endCompositing();
}
struct BlendStateBinder
@@ -120,41 +149,38 @@ struct BlendStateBinder
bool m_blend;
};
-void QEGLCompositor::render(QEGLPlatformWindow *window)
+void QOpenGLCompositor::render(QOpenGLCompositorWindow *window)
{
const QPlatformTextureList *textures = window->textures();
if (!textures)
return;
- const QRect targetWindowRect(QPoint(0, 0), window->screen()->geometry().size());
- glViewport(0, 0, targetWindowRect.width(), targetWindowRect.height());
-
+ const QRect targetWindowRect(QPoint(0, 0), m_targetWindow->geometry().size());
float currentOpacity = 1.0f;
BlendStateBinder blend;
for (int i = 0; i < textures->count(); ++i) {
uint textureId = textures->textureId(i);
- QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i),
- targetWindowRect);
- const float opacity = window->window()->opacity();
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect);
+ const float opacity = window->sourceWindow()->opacity();
if (opacity != currentOpacity) {
currentOpacity = opacity;
- m_blitter->setOpacity(currentOpacity);
+ m_blitter.setOpacity(currentOpacity);
}
if (textures->count() > 1 && i == textures->count() - 1) {
// Backingstore for a widget with QOpenGLWidget subwidgets
blend.set(true);
- m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
+ m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
} else if (textures->count() == 1) {
// A regular QWidget window
- const bool translucent = window->window()->requestedFormat().alphaBufferSize() > 0;
+ const bool translucent = window->sourceWindow()->requestedFormat().alphaBufferSize() > 0;
blend.set(translucent);
- m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
+ m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
} else if (!textures->stacksOnTop(i)) {
// Texture from an FBO belonging to a QOpenGLWidget
blend.set(false);
- m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft);
+ m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft);
}
}
@@ -162,24 +188,56 @@ void QEGLCompositor::render(QEGLPlatformWindow *window)
if (textures->stacksOnTop(i)) {
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect);
blend.set(true);
- m_blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft);
+ m_blitter.blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft);
}
}
- m_blitter->setOpacity(1.0f);
+ m_blitter.setOpacity(1.0f);
}
-QEGLCompositor *QEGLCompositor::instance()
+QOpenGLCompositor *QOpenGLCompositor::instance()
{
if (!compositor)
- compositor = new QEGLCompositor;
+ compositor = new QOpenGLCompositor;
return compositor;
}
-void QEGLCompositor::destroy()
+void QOpenGLCompositor::destroy()
{
delete compositor;
compositor = 0;
}
+void QOpenGLCompositor::addWindow(QOpenGLCompositorWindow *window)
+{
+ if (!m_windows.contains(window)) {
+ m_windows.append(window);
+ emit topWindowChanged(window);
+ }
+}
+
+void QOpenGLCompositor::removeWindow(QOpenGLCompositorWindow *window)
+{
+ m_windows.removeOne(window);
+ if (!m_windows.isEmpty())
+ emit topWindowChanged(m_windows.last());
+}
+
+void QOpenGLCompositor::moveToTop(QOpenGLCompositorWindow *window)
+{
+ m_windows.removeOne(window);
+ m_windows.append(window);
+ emit topWindowChanged(window);
+}
+
+void QOpenGLCompositor::changeWindowIndex(QOpenGLCompositorWindow *window, int newIdx)
+{
+ int idx = m_windows.indexOf(window);
+ if (idx != -1 && idx != newIdx) {
+ m_windows.move(idx, newIdx);
+ if (newIdx == m_windows.size() - 1)
+ emit topWindowChanged(m_windows.last());
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglcompositor_p.h b/src/platformsupport/platformcompositor/qopenglcompositor_p.h
index 1401fbdd55..9c876f5af1 100644
--- a/src/platformsupport/eglconvenience/qeglcompositor_p.h
+++ b/src/platformsupport/platformcompositor/qopenglcompositor_p.h
@@ -31,8 +31,8 @@
**
****************************************************************************/
-#ifndef QEGLCOMPOSITOR_H
-#define QEGLCOMPOSITOR_H
+#ifndef QOPENGLCOMPOSITOR_H
+#define QOPENGLCOMPOSITOR_H
//
// W A R N I N G
@@ -46,38 +46,62 @@
//
#include <QtCore/QTimer>
+#include <QtGui/private/qopengltextureblitter_p.h>
QT_BEGIN_NAMESPACE
class QOpenGLContext;
-class QOpenGLTextureBlitter;
-class QEGLPlatformWindow;
+class QWindow;
+class QPlatformTextureList;
-class QEGLCompositor : public QObject
+class QOpenGLCompositorWindow
+{
+public:
+ virtual QWindow *sourceWindow() const = 0;
+ virtual const QPlatformTextureList *textures() const = 0;
+ virtual void beginCompositing() { }
+ virtual void endCompositing() { }
+};
+
+class QOpenGLCompositor : public QObject
{
Q_OBJECT
public:
- void schedule(QOpenGLContext *context, QEGLPlatformWindow *window);
-
- static QEGLCompositor *instance();
+ static QOpenGLCompositor *instance();
static void destroy();
+ void setTarget(QOpenGLContext *context, QWindow *window);
+ QOpenGLContext *context() const { return m_context; }
+ QWindow *targetWindow() const { return m_targetWindow; }
+
+ void update();
+
+ QList<QOpenGLCompositorWindow *> windows() const { return m_windows; }
+ void addWindow(QOpenGLCompositorWindow *window);
+ void removeWindow(QOpenGLCompositorWindow *window);
+ void moveToTop(QOpenGLCompositorWindow *window);
+ void changeWindowIndex(QOpenGLCompositorWindow *window, int newIdx);
+
+signals:
+ void topWindowChanged(QOpenGLCompositorWindow *window);
+
private slots:
void renderAll();
private:
- QEGLCompositor();
- ~QEGLCompositor();
+ QOpenGLCompositor();
+ ~QOpenGLCompositor();
- void render(QEGLPlatformWindow *window);
+ void render(QOpenGLCompositorWindow *window);
QOpenGLContext *m_context;
- QEGLPlatformWindow *m_window;
+ QWindow *m_targetWindow;
QTimer m_updateTimer;
- QOpenGLTextureBlitter *m_blitter;
+ QOpenGLTextureBlitter m_blitter;
+ QList<QOpenGLCompositorWindow *> m_windows;
};
QT_END_NAMESPACE
-#endif // QEGLCOMPOSITOR_H
+#endif // QOPENGLCOMPOSITOR_H
diff --git a/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp
index 43c18573f2..9c254bead3 100644
--- a/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp
+++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp
@@ -31,62 +31,58 @@
**
****************************************************************************/
-#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLContext>
+#include <QtGui/QWindow>
#include <QtGui/QPainter>
+#include <qpa/qplatformbackingstore.h>
-#include "qeglplatformbackingstore_p.h"
-#include "qeglcompositor_p.h"
-#include "qeglplatformwindow_p.h"
-#include "qeglplatformscreen_p.h"
+#include "qopenglcompositorbackingstore_p.h"
+#include "qopenglcompositor_p.h"
QT_BEGIN_NAMESPACE
/*!
- \class QEGLPlatformBackingStore
- \brief A backing store implementation for EGL and GLES.
- \since 5.2
+ \class QOpenGLCompositorBackingStore
+ \brief A backing store implementation for OpenGL
+ \since 5.4
\internal
\ingroup qpa
This implementation uploads raster-rendered widget windows into
- textures and composites them onto a single native window using
- QEGLCompositor. This means that multiple top-level widgets are
- supported without creating actual native windows for each of them.
-
- The class is ready to be used as-is, the default
- QEGLPlatformIntegration::createPlatformBackingStore()
- implementation creates an instance which is ready to be used
- without further customization.
-
- If QEGLCompositor is not suitable, this backing store
- implementation can also be used without it. In this case a
- subclass must reimplement composite() and schedule an update in
- its custom compositor when this function is called. The textures
- are accessible via QEGLPlatformWindow::texture().
+ textures. It is meant to be used with QOpenGLCompositor that
+ composites the textures onto a single native window using OpenGL.
+ This means that multiple top-level widgets are supported without
+ creating actual native windows for each of them.
+
+ \note It is important to call notifyComposited() from the
+ corresponding platform window's endCompositing() callback
+ (inherited from QOpenGLCompositorWindow).
+
+ \note When implementing QOpenGLCompositorWindow::textures() for
+ windows of type RasterSurface or RasterGLSurface, simply return
+ the list provided by this class' textures().
*/
-QEGLPlatformBackingStore::QEGLPlatformBackingStore(QWindow *window)
+QOpenGLCompositorBackingStore::QOpenGLCompositorBackingStore(QWindow *window)
: QPlatformBackingStore(window),
- m_window(static_cast<QEGLPlatformWindow *>(window->handle())),
+ m_window(window),
m_bsTexture(0),
m_textures(new QPlatformTextureList),
m_lockedWidgetTextures(0)
{
- m_window->setBackingStore(this);
}
-QEGLPlatformBackingStore::~QEGLPlatformBackingStore()
+QOpenGLCompositorBackingStore::~QOpenGLCompositorBackingStore()
{
delete m_textures;
}
-QPaintDevice *QEGLPlatformBackingStore::paintDevice()
+QPaintDevice *QOpenGLCompositorBackingStore::paintDevice()
{
return &m_image;
}
-void QEGLPlatformBackingStore::updateTexture()
+void QOpenGLCompositorBackingStore::updateTexture()
{
if (!m_bsTexture) {
glGenTextures(1, &m_bsTexture);
@@ -134,7 +130,7 @@ void QEGLPlatformBackingStore::updateTexture()
}
}
-void QEGLPlatformBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+void QOpenGLCompositorBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
// Called for ordinary raster windows. This is rare since RasterGLSurface
// support is claimed which leads to having all QWidget windows marked as
@@ -144,35 +140,38 @@ void QEGLPlatformBackingStore::flush(QWindow *window, const QRegion &region, con
Q_UNUSED(region);
Q_UNUSED(offset);
- QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
- QEGLPlatformWindow *dstWin = screen->compositingWindow();
- if (!dstWin || !dstWin->isRaster())
+ QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
+ QOpenGLContext *dstCtx = compositor->context();
+ QWindow *dstWin = compositor->targetWindow();
+ if (!dstWin)
return;
- screen->compositingContext()->makeCurrent(dstWin->window());
+ dstCtx->makeCurrent(dstWin);
updateTexture();
m_textures->clear();
m_textures->appendTexture(m_bsTexture, window->geometry());
- composite(screen->compositingContext(), dstWin);
+
+ compositor->update();
}
-void QEGLPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
+void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
QPlatformTextureList *textures, QOpenGLContext *context,
bool translucentBackground)
{
- // QOpenGLWidget content provided as textures. The raster content should go on top.
+ // QOpenGLWidget/QQuickWidget content provided as textures. The raster content should go on top.
Q_UNUSED(region);
Q_UNUSED(offset);
Q_UNUSED(context);
Q_UNUSED(translucentBackground);
- QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
- QEGLPlatformWindow *dstWin = screen->compositingWindow();
- if (!dstWin || !dstWin->isRaster())
+ QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
+ QOpenGLContext *dstCtx = compositor->context();
+ QWindow *dstWin = compositor->targetWindow();
+ if (!dstWin)
return;
- screen->compositingContext()->makeCurrent(dstWin->window());
+ dstCtx->makeCurrent(dstWin);
m_textures->clear();
for (int i = 0; i < textures->count(); ++i)
@@ -184,15 +183,10 @@ void QEGLPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &r
textures->lock(true);
m_lockedWidgetTextures = textures;
- composite(screen->compositingContext(), dstWin);
-}
-
-void QEGLPlatformBackingStore::composite(QOpenGLContext *context, QEGLPlatformWindow *window)
-{
- QEGLCompositor::instance()->schedule(context, window);
+ compositor->update();
}
-void QEGLPlatformBackingStore::composited()
+void QOpenGLCompositorBackingStore::notifyComposited()
{
if (m_lockedWidgetTextures) {
QPlatformTextureList *textureList = m_lockedWidgetTextures;
@@ -201,7 +195,7 @@ void QEGLPlatformBackingStore::composited()
}
}
-void QEGLPlatformBackingStore::beginPaint(const QRegion &region)
+void QOpenGLCompositorBackingStore::beginPaint(const QRegion &region)
{
m_dirty |= region;
@@ -213,27 +207,28 @@ void QEGLPlatformBackingStore::beginPaint(const QRegion &region)
}
}
-void QEGLPlatformBackingStore::resize(const QSize &size, const QRegion &staticContents)
+void QOpenGLCompositorBackingStore::resize(const QSize &size, const QRegion &staticContents)
{
Q_UNUSED(staticContents);
- QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
- QEGLPlatformWindow *dstWin = screen->compositingWindow();
- if (!dstWin || (!dstWin->isRaster() && dstWin->window()->surfaceType() != QSurface::RasterGLSurface))
+ QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
+ QOpenGLContext *dstCtx = compositor->context();
+ QWindow *dstWin = compositor->targetWindow();
+ if (!dstWin)
return;
m_image = QImage(size, QImage::Format_RGBA8888);
m_window->create();
- screen->compositingContext()->makeCurrent(dstWin->window());
+ dstCtx->makeCurrent(dstWin);
if (m_bsTexture) {
glDeleteTextures(1, &m_bsTexture);
m_bsTexture = 0;
}
}
-QImage QEGLPlatformBackingStore::toImage() const
+QImage QOpenGLCompositorBackingStore::toImage() const
{
return m_image;
}
diff --git a/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore_p.h
index 502ca5a639..0501cd868c 100644
--- a/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h
+++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore_p.h
@@ -31,8 +31,8 @@
**
****************************************************************************/
-#ifndef QEGLPLATFORMBACKINGSTORE_H
-#define QEGLPLATFORMBACKINGSTORE_H
+#ifndef QOPENGLCOMPOSITORBACKINGSTORE_H
+#define QOPENGLCOMPOSITORBACKINGSTORE_H
//
// W A R N I N G
@@ -46,7 +46,6 @@
//
#include <qpa/qplatformbackingstore.h>
-
#include <QImage>
#include <QRegion>
@@ -54,13 +53,12 @@ QT_BEGIN_NAMESPACE
class QOpenGLContext;
class QPlatformTextureList;
-class QEGLPlatformWindow;
-class QEGLPlatformBackingStore : public QPlatformBackingStore
+class QOpenGLCompositorBackingStore : public QPlatformBackingStore
{
public:
- QEGLPlatformBackingStore(QWindow *window);
- ~QEGLPlatformBackingStore();
+ QOpenGLCompositorBackingStore(QWindow *window);
+ ~QOpenGLCompositorBackingStore();
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
@@ -76,14 +74,12 @@ public:
const QPlatformTextureList *textures() const { return m_textures; }
- virtual void composite(QOpenGLContext *context, QEGLPlatformWindow *window);
-
- void composited();
+ void notifyComposited();
private:
void updateTexture();
- QEGLPlatformWindow *m_window;
+ QWindow *m_window;
QImage m_image;
QRegion m_dirty;
uint m_bsTexture;
@@ -93,4 +89,4 @@ private:
QT_END_NAMESPACE
-#endif // QEGLPLATFORMBACKINGSTORE_H
+#endif // QOPENGLCOMPOSITORBACKINGSTORE_H
diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro
index 32ce2e3887..39cbd9d181 100644
--- a/src/platformsupport/platformsupport.pro
+++ b/src/platformsupport/platformsupport.pro
@@ -21,5 +21,6 @@ include(themes/themes.pri)
include(accessibility/accessibility.pri)
include(linuxaccessibility/linuxaccessibility.pri)
include(clipboard/clipboard.pri)
+include(platformcompositor/platformcompositor.pri)
load(qt_module)
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index 60f7347ba5..a66cff165b 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -41,9 +41,7 @@ QT_BEGIN_NAMESPACE
QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
: QEGLPlatformScreen(dpy),
m_surface(EGL_NO_SURFACE),
- m_cursor(0),
- m_rootWindow(0),
- m_rootContext(0)
+ m_cursor(0)
{
m_cursor = QEglFSHooks::hooks()->createCursor(this);
}
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
index c5ab3b52f5..d109ad9d9b 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.h
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -64,12 +64,6 @@ public:
EGLSurface primarySurface() const { return m_surface; }
- QEGLPlatformWindow *compositingWindow() Q_DECL_OVERRIDE { return m_rootWindow; }
- QOpenGLContext *compositingContext() Q_DECL_OVERRIDE { return m_rootContext; }
-
- void setRootWindow(QEGLPlatformWindow *window) { m_rootWindow = window; }
- void setRootContext(QOpenGLContext *context) { m_rootContext = context; }
-
protected:
void setPrimarySurface(EGLSurface surface);
@@ -78,8 +72,6 @@ private:
EGLSurface m_surface;
QPlatformCursor *m_cursor;
- QEGLPlatformWindow *m_rootWindow;
- QOpenGLContext *m_rootContext;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp
index 59c2014d66..0ab19e6065 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp
@@ -39,7 +39,6 @@
#include <QtGui/QOpenGLContext>
#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
-
#include <QtDebug>
QT_BEGIN_NAMESPACE
@@ -73,9 +72,10 @@ void QEglFSWindow::create()
// raster windows will not have their own native window, surface and context. Instead,
// they will be composited onto the root window's surface.
QEglFSScreen *screen = this->screen();
+ QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
if (screen->primarySurface() != EGL_NO_SURFACE) {
- if (isRaster() && screen->compositingWindow()) {
- m_format = screen->compositingWindow()->format();
+ if (isRaster() && compositor->targetWindow()) {
+ m_format = compositor->targetWindow()->format();
return;
}
@@ -107,8 +107,7 @@ void QEglFSWindow::create()
context->setScreen(window()->screen());
if (!context->create())
qFatal("EGLFS: Failed to create compositing context");
- screen->setRootContext(context);
- screen->setRootWindow(this);
+ compositor->setTarget(context, window());
}
}
@@ -127,7 +126,7 @@ void QEglFSWindow::destroy()
}
m_flags = 0;
- screen->removeWindow(this);
+ QOpenGLCompositor::instance()->removeWindow(this);
}
// The virtual functions resetSurface and invalidateSurface may get overridden
@@ -160,17 +159,18 @@ void QEglFSWindow::resetSurface()
void QEglFSWindow::setVisible(bool visible)
{
- QList<QEGLPlatformWindow *> windows = screen()->windows();
+ QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
+ QList<QOpenGLCompositorWindow *> windows = compositor->windows();
QWindow *wnd = window();
if (wnd->type() != Qt::Desktop) {
if (visible) {
- screen()->addWindow(this);
+ compositor->addWindow(this);
} else {
- screen()->removeWindow(this);
- windows = screen()->windows();
+ compositor->removeWindow(this);
+ windows = compositor->windows();
if (windows.size())
- windows.last()->requestActivateWindow();
+ windows.last()->sourceWindow()->requestActivate();
}
}
@@ -210,7 +210,7 @@ QRect QEglFSWindow::geometry() const
void QEglFSWindow::requestActivateWindow()
{
if (window()->type() != Qt::Desktop)
- screen()->moveToTop(this);
+ QOpenGLCompositor::instance()->moveToTop(this);
QWindow *wnd = window();
QWindowSystemInterface::handleWindowActivated(wnd);
@@ -221,20 +221,21 @@ void QEglFSWindow::raise()
{
QWindow *wnd = window();
if (wnd->type() != Qt::Desktop) {
- screen()->moveToTop(this);
+ QOpenGLCompositor::instance()->moveToTop(this);
QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size()));
}
}
void QEglFSWindow::lower()
{
- QList<QEGLPlatformWindow *> windows = screen()->windows();
+ QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
+ QList<QOpenGLCompositorWindow *> windows = compositor->windows();
if (window()->type() != Qt::Desktop && windows.count() > 1) {
int idx = windows.indexOf(this);
if (idx > 0) {
- screen()->changeWindowIndex(this, idx - 1);
- QWindowSystemInterface::handleExposeEvent(windows.last()->window(),
- QRect(QPoint(0, 0), windows.last()->geometry().size()));
+ compositor->changeWindowIndex(this, idx - 1);
+ QWindowSystemInterface::handleExposeEvent(windows.last()->sourceWindow(),
+ QRect(QPoint(0, 0), windows.last()->sourceWindow()->geometry().size()));
}
}
}