Add generic OpenGL compositor and backingstore bits

By removing the EGL(FS) dependencies we get classes that can be used
by any platform plugin that runs without a windowing system.

Change-Id: If99b42de5a4da02bbef80863609b6d92c6734613
Reviewed-by: Jørgen Lind <jorgen.lind@theqtcompany.com>
bb10
Laszlo Agocs 2014-11-19 14:58:43 +01:00 committed by Laszlo Agocs
parent e41713b21d
commit 37cce4cada
15 changed files with 260 additions and 238 deletions

View File

@ -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
}
}

View File

@ -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(),

View File

@ -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

View File

@ -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;
};

View File

@ -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

View File

@ -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;
};

View File

@ -0,0 +1,7 @@
contains(QT_CONFIG, opengl) {
SOURCES += $$PWD/qopenglcompositor.cpp \
$$PWD/qopenglcompositorbackingstore.cpp
HEADERS += $$PWD/qopenglcompositor_p.h \
$$PWD/qopenglcompositorbackingstore_p.h
}

View File

@ -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);
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));
const QRect targetWindowRect(QPoint(0, 0), m_targetWindow->geometry().size());
glViewport(0, 0, targetWindowRect.width(), targetWindowRect.height());
m_blitter->release();
m_context->swapBuffers(m_window->window());
if (!m_blitter.isCreated())
m_blitter.create();
for (int i = 0; i < windows.size(); ++i)
windows.at(i)->composited();
m_blitter.bind();
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

View File

@ -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

View File

@ -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.
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.
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.
\note It is important to call notifyComposited() from the
corresponding platform window's endCompositing() callback
(inherited from QOpenGLCompositorWindow).
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().
\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);
compositor->update();
}
void QEGLPlatformBackingStore::composite(QOpenGLContext *context, QEGLPlatformWindow *window)
{
QEGLCompositor::instance()->schedule(context, window);
}
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;
}

View File

@ -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

View File

@ -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)

View File

@ -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);
}

View File

@ -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

View File

@ -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()));
}
}
}