summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp6
-rw-r--r--src/gui/painting/qplatformbackingstore.h2
-rw-r--r--src/platformsupport/eglconvenience/qeglcompositor.cpp134
-rw-r--r--src/platformsupport/eglconvenience/qeglcompositor_p.h10
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp100
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h22
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext.cpp17
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformintegration.cpp22
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformintegration_p.h10
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformwindow.cpp18
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformwindow_p.h6
-rw-r--r--src/plugins/platforms/eglfs/eglfs.pri2
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp25
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.h9
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp4
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.cpp6
-rw-r--r--src/widgets/kernel/qwidgetbackingstore.cpp35
-rw-r--r--src/widgets/kernel/qwidgetbackingstore_p.h20
-rw-r--r--tests/manual/qopenglwidget/openglwidget/openglwidget.cpp2
19 files changed, 275 insertions, 175 deletions
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index d2b1f056d7..a77fbb6826 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -156,6 +156,12 @@ void QPlatformTextureList::appendTexture(GLuint textureId, const QRect &geometry
bi.rect = geometry;
d->textures.append(bi);
}
+
+void QPlatformTextureList::clear()
+{
+ Q_D(QPlatformTextureList);
+ d->textures.clear();
+}
#endif // QT_NO_OPENGL
/*!
diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h
index a662a2290b..76fd3d40b4 100644
--- a/src/gui/painting/qplatformbackingstore.h
+++ b/src/gui/painting/qplatformbackingstore.h
@@ -81,12 +81,14 @@ public:
~QPlatformTextureList();
int count() const;
+ bool isEmpty() const { return count() == 0; }
GLuint textureId(int index) const;
QRect geometry(int index) const;
void lock(bool on);
bool isLocked() const;
void appendTexture(GLuint textureId, const QRect &geometry);
+ void clear();
Q_SIGNALS:
void locked(bool);
diff --git a/src/platformsupport/eglconvenience/qeglcompositor.cpp b/src/platformsupport/eglconvenience/qeglcompositor.cpp
index f81d72c4bd..aac4822f66 100644
--- a/src/platformsupport/eglconvenience/qeglcompositor.cpp
+++ b/src/platformsupport/eglconvenience/qeglcompositor.cpp
@@ -42,6 +42,8 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QOpenGLFramebufferObject>
+#include <QtGui/private/qopengltextureblitter_p.h>
+#include <qpa/qplatformbackingstore.h>
#include "qeglcompositor_p.h"
#include "qeglplatformwindow_p.h"
@@ -54,7 +56,7 @@ static QEGLCompositor *compositor = 0;
QEGLCompositor::QEGLCompositor()
: m_context(0),
m_window(0),
- m_program(0)
+ m_blitter(0)
{
Q_ASSERT(!compositor);
m_updateTimer.setSingleShot(true);
@@ -65,7 +67,10 @@ QEGLCompositor::QEGLCompositor()
QEGLCompositor::~QEGLCompositor()
{
Q_ASSERT(compositor == this);
- delete m_program;
+ if (m_blitter) {
+ m_blitter->destroy();
+ delete m_blitter;
+ }
compositor = 0;
}
@@ -81,102 +86,53 @@ void QEGLCompositor::renderAll()
{
Q_ASSERT(m_context && m_window);
m_context->makeCurrent(m_window->window());
- ensureProgram();
- m_program->bind();
+
+ if (!m_blitter) {
+ m_blitter = new QOpenGLTextureBlitter;
+ m_blitter->create();
+ }
+ m_blitter->bind();
QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
QList<QEGLPlatformWindow *> windows = screen->windows();
- for (int i = 0; i < windows.size(); ++i) {
- QEGLPlatformWindow *window = windows.at(i);
- uint texture = window->texture();
- if (texture)
- render(window, texture, window->isRaster());
- }
+ for (int i = 0; i < windows.size(); ++i)
+ render(windows.at(i));
- m_program->release();
+ m_blitter->release();
m_context->swapBuffers(m_window->window());
-}
-void QEGLCompositor::ensureProgram()
-{
- if (!m_program) {
- static const char *textureVertexProgram =
- "attribute highp vec2 vertexCoordEntry;\n"
- "attribute highp vec2 textureCoordEntry;\n"
- "varying highp vec2 textureCoord;\n"
- "void main() {\n"
- " textureCoord = textureCoordEntry;\n"
- " gl_Position = vec4(vertexCoordEntry, 0.0, 1.0);\n"
- "}\n";
-
- static const char *textureFragmentProgram =
- "uniform sampler2D texture;\n"
- "varying highp vec2 textureCoord;\n"
- "uniform bool isRaster;\n"
- "void main() {\n"
- " lowp vec4 c = texture2D(texture, textureCoord);\n"
- " gl_FragColor = isRaster ? c.bgra : c.rgba;\n"
- "}\n";
-
- m_program = new QOpenGLShaderProgram;
-
- m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
- m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
- m_program->link();
-
- m_vertexCoordEntry = m_program->attributeLocation("vertexCoordEntry");
- m_textureCoordEntry = m_program->attributeLocation("textureCoordEntry");
- m_isRasterEntry = m_program->uniformLocation("isRaster");
- }
+ for (int i = 0; i < windows.size(); ++i)
+ windows.at(i)->composited();
}
-void QEGLCompositor::render(QEGLPlatformWindow *window, uint texture, bool raster)
+void QEGLCompositor::render(QEGLPlatformWindow *window)
{
- const GLfloat textureCoordinates[] = {
- 0, 0,
- 1, 0,
- 1, 1,
- 0, 1
- };
-
- QRectF sr = window->screen()->geometry();
- QRect r = window->window()->geometry();
- QPoint tl = r.topLeft();
- QPoint br = r.bottomRight();
-
- // Map to [-1,1]
- GLfloat x1 = (tl.x() / sr.width()) * 2 - 1;
- GLfloat y1 = ((sr.height() - tl.y()) / sr.height()) * 2 - 1;
- GLfloat x2 = ((br.x() + 1) / sr.width()) * 2 - 1;
- GLfloat y2 = ((sr.height() - (br.y() + 1)) / sr.height()) * 2 - 1;
-
- if (!raster)
- qSwap(y1, y2);
-
- const GLfloat vertexCoordinates[] = {
- x1, y1,
- x2, y1,
- x2, y2,
- x1, y2
- };
-
- glViewport(0, 0, sr.width(), sr.height());
-
- m_program->enableAttributeArray(m_vertexCoordEntry);
- m_program->enableAttributeArray(m_textureCoordEntry);
-
- m_program->setAttributeArray(m_vertexCoordEntry, vertexCoordinates, 2);
- m_program->setAttributeArray(m_textureCoordEntry, textureCoordinates, 2);
-
- glBindTexture(GL_TEXTURE_2D, texture);
-
- m_program->setUniformValue(m_isRasterEntry, raster);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- glBindTexture(GL_TEXTURE_2D, 0);
- m_program->enableAttributeArray(m_textureCoordEntry);
- m_program->enableAttributeArray(m_vertexCoordEntry);
+ 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());
+
+ for (int i = 0; i < textures->count(); ++i) {
+ uint textureId = textures->textureId(i);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i),
+ targetWindowRect,
+ QOpenGLTextureBlitter::OriginTopLeft);
+ m_blitter->setSwizzleRB(window->isRaster());
+
+ if (textures->count() > 1 && i == textures->count() - 1) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
+ glDisable(GL_BLEND);
+ } else if (textures->count() == 1) {
+ m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
+ } else {
+ m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft);
+ }
+ }
}
QEGLCompositor *QEGLCompositor::instance()
diff --git a/src/platformsupport/eglconvenience/qeglcompositor_p.h b/src/platformsupport/eglconvenience/qeglcompositor_p.h
index 28e770e408..370345ada6 100644
--- a/src/platformsupport/eglconvenience/qeglcompositor_p.h
+++ b/src/platformsupport/eglconvenience/qeglcompositor_p.h
@@ -46,8 +46,8 @@
QT_BEGIN_NAMESPACE
-class QOpenGLShaderProgram;
class QOpenGLContext;
+class QOpenGLTextureBlitter;
class QEGLPlatformWindow;
class QEGLCompositor : public QObject
@@ -67,16 +67,12 @@ private:
QEGLCompositor();
~QEGLCompositor();
- void render(QEGLPlatformWindow *window, uint texture, bool raster);
- void ensureProgram();
+ void render(QEGLPlatformWindow *window);
QOpenGLContext *m_context;
QEGLPlatformWindow *m_window;
QTimer m_updateTimer;
- QOpenGLShaderProgram *m_program;
- int m_vertexCoordEntry;
- int m_textureCoordEntry;
- int m_isRasterEntry;
+ QOpenGLTextureBlitter *m_blitter;
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp b/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp
index 6a22c01a83..24e9ccd39f 100644
--- a/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp
@@ -76,11 +76,18 @@ QT_BEGIN_NAMESPACE
QEGLPlatformBackingStore::QEGLPlatformBackingStore(QWindow *window)
: QPlatformBackingStore(window),
m_window(static_cast<QEGLPlatformWindow *>(window->handle())),
- m_texture(0)
+ m_bsTexture(0),
+ m_textures(new QPlatformTextureList),
+ m_lockedWidgetTextures(0)
{
m_window->setBackingStore(this);
}
+QEGLPlatformBackingStore::~QEGLPlatformBackingStore()
+{
+ delete m_textures;
+}
+
QPaintDevice *QEGLPlatformBackingStore::paintDevice()
{
return &m_image;
@@ -88,7 +95,18 @@ QPaintDevice *QEGLPlatformBackingStore::paintDevice()
void QEGLPlatformBackingStore::updateTexture()
{
- glBindTexture(GL_TEXTURE_2D, m_texture);
+ if (!m_bsTexture) {
+ glGenTextures(1, &m_bsTexture);
+ glBindTexture(GL_TEXTURE_2D, m_bsTexture);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ // QOpenGLTextureBlitter requires GL_REPEAT for the time being
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_image.width(), m_image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, m_bsTexture);
+ }
if (!m_dirty.isNull()) {
QRegion fixed;
@@ -126,24 +144,56 @@ void QEGLPlatformBackingStore::updateTexture()
void QEGLPlatformBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
- Q_UNUSED(window);
+ // Called for ordinary raster windows. This is rare since RasterGLSurface
+ // support is claimed which leads to having all QWidget windows marked as
+ // RasterGLSurface instead of just Raster. These go through
+ // compositeAndFlush() instead of this function.
+
Q_UNUSED(region);
Q_UNUSED(offset);
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglBackingStore::flush %p", window);
-#endif
+ QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
+ QEGLPlatformWindow *dstWin = screen->compositingWindow();
+ if (!dstWin || !dstWin->isRaster())
+ return;
+
+ screen->compositingContext()->makeCurrent(dstWin->window());
+ updateTexture();
+ m_textures->clear();
+ m_textures->appendTexture(m_bsTexture, window->geometry());
+ composite(screen->compositingContext(), dstWin);
+}
+
+void QEGLPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
+ QPlatformTextureList *textures, QOpenGLContext *context)
+{
+ // QOpenGLWidget content provided as textures. The raster content should go on top.
+
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
+ Q_UNUSED(context);
QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
QEGLPlatformWindow *dstWin = screen->compositingWindow();
if (!dstWin || !dstWin->isRaster())
return;
- m_window->create();
- QOpenGLContext *context = screen->compositingContext();
- context->makeCurrent(dstWin->window());
+ screen->compositingContext()->makeCurrent(dstWin->window());
+
+ m_textures->clear();
+ for (int i = 0; i < textures->count(); ++i) {
+ uint textureId = textures->textureId(i);
+ QRect geom = textures->geometry(i);
+ m_textures->appendTexture(textureId, geom);
+ }
+
updateTexture();
- composite(context, dstWin);
+ m_textures->appendTexture(m_bsTexture, window->geometry());
+
+ textures->lock(true);
+ m_lockedWidgetTextures = textures;
+
+ composite(screen->compositingContext(), dstWin);
}
void QEGLPlatformBackingStore::composite(QOpenGLContext *context, QEGLPlatformWindow *window)
@@ -151,6 +201,15 @@ void QEGLPlatformBackingStore::composite(QOpenGLContext *context, QEGLPlatformWi
QEGLCompositor::instance()->schedule(context, window);
}
+void QEGLPlatformBackingStore::composited()
+{
+ if (m_lockedWidgetTextures) {
+ QPlatformTextureList *textureList = m_lockedWidgetTextures;
+ m_lockedWidgetTextures = 0; // may reenter so null before unlocking
+ textureList->lock(false);
+ }
+}
+
void QEGLPlatformBackingStore::beginPaint(const QRegion &rgn)
{
m_dirty |= rgn;
@@ -162,25 +221,22 @@ void QEGLPlatformBackingStore::resize(const QSize &size, const QRegion &staticCo
QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
QEGLPlatformWindow *dstWin = screen->compositingWindow();
- if (!dstWin || !dstWin->isRaster())
+ if (!dstWin || (!dstWin->isRaster() && dstWin->window()->surfaceType() != QSurface::RasterGLSurface))
return;
m_image = QImage(size, QImage::Format_RGB32);
m_window->create();
screen->compositingContext()->makeCurrent(dstWin->window());
+ if (m_bsTexture) {
+ glDeleteTextures(1, &m_bsTexture);
+ m_bsTexture = 0;
+ }
+}
- if (m_texture)
- glDeleteTextures(1, &m_texture);
-
- glGenTextures(1, &m_texture);
- glBindTexture(GL_TEXTURE_2D, m_texture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+QImage QEGLPlatformBackingStore::toImage() const
+{
+ return m_image;
}
QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h b/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h
index 58fc386892..cb1e5999b0 100644
--- a/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h
+++ b/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h
@@ -50,31 +50,41 @@
QT_BEGIN_NAMESPACE
class QOpenGLContext;
+class QPlatformTextureList;
class QEGLPlatformWindow;
class QEGLPlatformBackingStore : public QPlatformBackingStore
{
public:
QEGLPlatformBackingStore(QWindow *window);
+ ~QEGLPlatformBackingStore();
- QPaintDevice *paintDevice();
+ QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
- void beginPaint(const QRegion &);
+ void beginPaint(const QRegion &) Q_DECL_OVERRIDE;
- void flush(QWindow *window, const QRegion &region, const QPoint &offset);
- void resize(const QSize &size, const QRegion &staticContents);
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
+ void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE;
- uint texture() const { return m_texture; }
+ QImage toImage() const Q_DECL_OVERRIDE;
+ void composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
+ QPlatformTextureList *textures, QOpenGLContext *context) Q_DECL_OVERRIDE;
+
+ const QPlatformTextureList *textures() const { return m_textures; }
virtual void composite(QOpenGLContext *context, QEGLPlatformWindow *window);
+ void composited();
+
private:
void updateTexture();
QEGLPlatformWindow *m_window;
QImage m_image;
- uint m_texture;
QRegion m_dirty;
+ uint m_bsTexture;
+ QPlatformTextureList *m_textures;
+ QPlatformTextureList *m_lockedWidgetTextures;
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
index 614d086178..37875b1e2b 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
@@ -127,11 +127,8 @@ void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLCont
bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
{
- Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
+ Q_ASSERT(surface->surface()->supportsOpenGL());
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::makeCurrent: %p\n",this);
-#endif
bindApi(m_format);
EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface);
@@ -192,9 +189,6 @@ bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
QEGLPlatformContext::~QEGLPlatformContext()
{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::~QEglContext(): %p\n",this);
-#endif
if (m_eglContext != EGL_NO_CONTEXT) {
eglDestroyContext(m_eglDisplay, m_eglContext);
m_eglContext = EGL_NO_CONTEXT;
@@ -203,9 +197,6 @@ QEGLPlatformContext::~QEGLPlatformContext()
void QEGLPlatformContext::doneCurrent()
{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::doneCurrent:%p\n",this);
-#endif
bindApi(m_format);
bool ok = eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (!ok)
@@ -214,9 +205,6 @@ void QEGLPlatformContext::doneCurrent()
void QEGLPlatformContext::swapBuffers(QPlatformSurface *surface)
{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::swapBuffers:%p\n",this);
-#endif
bindApi(m_format);
EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface);
bool ok = eglSwapBuffers(m_eglDisplay, eglSurface);
@@ -226,9 +214,6 @@ void QEGLPlatformContext::swapBuffers(QPlatformSurface *surface)
void (*QEGLPlatformContext::getProcAddress(const QByteArray &procName)) ()
{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::getProcAddress%p\n",this);
-#endif
bindApi(m_format);
return eglGetProcAddress(procName.constData());
}
diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp
index 5fc1721f6c..a961035e22 100644
--- a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp
@@ -41,6 +41,7 @@
#include <QtGui/QWindow>
#include <QtGui/QOpenGLContext>
+#include <QtGui/QOffscreenSurface>
#include <QtGui/QGuiApplication>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatforminputcontextfactory_p.h>
@@ -79,8 +80,7 @@ QT_BEGIN_NAMESPACE
The backing store, native interface accessors, font database,
basic capability flags, etc. are provided out of the box, no
- further customization is needed. Subclasses are still responsible
- however for context and offscreen surface creation.
+ further customization is needed.
\note It is critical that this class' implementation of
initialize() is called. Therefore subclasses should either avoid
@@ -155,6 +155,23 @@ QPlatformWindow *QEGLPlatformIntegration::createPlatformWindow(QWindow *window)
return w;
}
+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;
+ return createContext(context->format(),
+ compositingContext ? compositingContext->handle() : context->shareHandle(),
+ display());
+}
+
+QPlatformOffscreenSurface *QEGLPlatformIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
+{
+ QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(surface->screen()->handle());
+ return createOffscreenSurface(screen->display(), surface->requestedFormat(), surface);
+}
+
bool QEGLPlatformIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
@@ -162,6 +179,7 @@ bool QEGLPlatformIntegration::hasCapability(QPlatformIntegration::Capability cap
case OpenGL: return true;
case ThreadedOpenGL: return true;
case WindowManagement: return false;
+ case RasterGLSurface: return true;
default: return QPlatformIntegration::hasCapability(cap);
}
}
diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h
index d3c3f07aff..f665455383 100644
--- a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h
+++ b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h
@@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE
class QEGLPlatformScreen;
class QEGLPlatformWindow;
+class QEGLPlatformContext;
class QFbVtHandler;
class QEGLPlatformIntegration : public QPlatformIntegration, public QPlatformNativeInterface
@@ -70,6 +71,8 @@ public:
QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
+ QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
@@ -83,6 +86,13 @@ public:
protected:
virtual QEGLPlatformScreen *createScreen() const = 0;
virtual QEGLPlatformWindow *createWindow(QWindow *window) const = 0;
+ virtual QEGLPlatformContext *createContext(const QSurfaceFormat &format,
+ QPlatformOpenGLContext *shareContext,
+ EGLDisplay display) const = 0;
+ virtual QPlatformOffscreenSurface *createOffscreenSurface(EGLDisplay display,
+ const QSurfaceFormat &format,
+ QOffscreenSurface *surface) const = 0;
+
virtual EGLNativeDisplayType nativeDisplay() const { return EGL_DEFAULT_DISPLAY; }
void createInputHandlers();
diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow.cpp b/src/platformsupport/eglconvenience/qeglplatformwindow.cpp
index a635bfff29..e9b79512ba 100644
--- a/src/platformsupport/eglconvenience/qeglplatformwindow.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformwindow.cpp
@@ -92,7 +92,8 @@ void QEGLPlatformWindow::create()
// Save the original surface type before changing to OpenGLSurface.
m_raster = (window()->surfaceType() == QSurface::RasterSurface);
- window()->setSurfaceType(QSurface::OpenGLSurface);
+ if (m_raster) // change to OpenGL, but not for RasterGLSurface
+ window()->setSurfaceType(QSurface::OpenGLSurface);
if (window()->type() == Qt::Desktop) {
QRect fullscreenRect(QPoint(), screen()->availableGeometry().size());
@@ -102,14 +103,25 @@ void QEGLPlatformWindow::create()
}
}
-uint QEGLPlatformWindow::texture() const
+bool QEGLPlatformWindow::isRaster() const
+{
+ return m_raster || window()->surfaceType() == QSurface::RasterGLSurface;
+}
+
+const QPlatformTextureList *QEGLPlatformWindow::textures() const
{
if (m_backingStore)
- return m_backingStore->texture();
+ return m_backingStore->textures();
return 0;
}
+void QEGLPlatformWindow::composited()
+{
+ if (m_backingStore)
+ m_backingStore->composited();
+}
+
WId QEGLPlatformWindow::winId() const
{
return m_winId;
diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow_p.h b/src/platformsupport/eglconvenience/qeglplatformwindow_p.h
index 770c741623..17a1d07a79 100644
--- a/src/platformsupport/eglconvenience/qeglplatformwindow_p.h
+++ b/src/platformsupport/eglconvenience/qeglplatformwindow_p.h
@@ -48,6 +48,7 @@
QT_BEGIN_NAMESPACE
class QEGLPlatformBackingStore;
+class QPlatformTextureList;
class QEGLPlatformWindow : public QPlatformWindow
{
@@ -58,8 +59,9 @@ public:
QEGLPlatformBackingStore *backingStore() { return m_backingStore; }
void setBackingStore(QEGLPlatformBackingStore *backingStore) { m_backingStore = backingStore; }
- uint texture() const;
- bool isRaster() const { return m_raster; }
+ const QPlatformTextureList *textures() const;
+ void composited();
+ bool isRaster() const;
WId winId() const Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/eglfs/eglfs.pri b/src/plugins/platforms/eglfs/eglfs.pri
index 7afa9c9e11..6e3ba54b97 100644
--- a/src/plugins/platforms/eglfs/eglfs.pri
+++ b/src/plugins/platforms/eglfs/eglfs.pri
@@ -1,7 +1,5 @@
QT += core-private gui-private platformsupport-private
-#DEFINES += QEGL_EXTRA_DEBUG
-
# Avoid X11 header collision
DEFINES += MESA_EGL_NO_X11_HEADERS
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index 472e58cc72..2941806f17 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -88,17 +88,6 @@ bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
return QEGLPlatformIntegration::hasCapability(cap);
}
-QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
-{
- return new QEglFSContext(QEglFSHooks::hooks()->surfaceFormatFor(context->format()), context->shareHandle(), display());
-}
-
-QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
-{
- QEglFSScreen *screen = static_cast<QEglFSScreen *>(surface->screen()->handle());
- return new QEGLPbuffer(screen->display(), QEglFSHooks::hooks()->surfaceFormatFor(surface->requestedFormat()), surface);
-}
-
void QEglFSIntegration::initialize()
{
QEglFSHooks::hooks()->platformInit();
@@ -124,6 +113,20 @@ QEGLPlatformWindow *QEglFSIntegration::createWindow(QWindow *window) const
return new QEglFSWindow(window);
}
+QEGLPlatformContext *QEglFSIntegration::createContext(const QSurfaceFormat &format,
+ QPlatformOpenGLContext *shareContext,
+ EGLDisplay display) const
+{
+ return new QEglFSContext(QEglFSHooks::hooks()->surfaceFormatFor(format), shareContext, display);
+}
+
+QPlatformOffscreenSurface *QEglFSIntegration::createOffscreenSurface(EGLDisplay display,
+ const QSurfaceFormat &format,
+ QOffscreenSurface *surface) const
+{
+ return new QEGLPbuffer(display, QEglFSHooks::hooks()->surfaceFormatFor(format), surface);
+}
+
QVariant QEglFSIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
{
switch (hint)
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h
index 9ff5bd6f3b..99dda1ea96 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.h
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.h
@@ -54,9 +54,6 @@ public:
QEglFSIntegration();
~QEglFSIntegration();
- QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
- QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
-
void initialize() Q_DECL_OVERRIDE;
bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
@@ -67,6 +64,12 @@ public:
protected:
QEGLPlatformScreen *createScreen() const Q_DECL_OVERRIDE;
QEGLPlatformWindow *createWindow(QWindow *window) const Q_DECL_OVERRIDE;
+ QEGLPlatformContext *createContext(const QSurfaceFormat &format,
+ QPlatformOpenGLContext *shareContext,
+ EGLDisplay display) const Q_DECL_OVERRIDE;
+ QPlatformOffscreenSurface *createOffscreenSurface(EGLDisplay display,
+ const QSurfaceFormat &format,
+ QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
EGLNativeDisplayType nativeDisplay() const Q_DECL_OVERRIDE;
private:
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index 11c1160ce9..31f6ac5be6 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -53,10 +53,6 @@ QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
m_rootWindow(0),
m_rootContext(0)
{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglScreen %p\n", this);
-#endif
-
m_cursor = QEglFSHooks::hooks()->createCursor(this);
}
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp
index 279e7bbc91..2d36c0b58e 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp
@@ -58,9 +58,6 @@ QEglFSWindow::QEglFSWindow(QWindow *w)
, m_window(0)
, m_flags(0)
{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglWindow %p: %p 0x%x\n", this, w, uint(m_window));
-#endif
}
QEglFSWindow::~QEglFSWindow()
@@ -114,7 +111,8 @@ void QEglFSWindow::create()
QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance());
context->setFormat(window()->requestedFormat());
context->setScreen(window()->screen());
- context->create();
+ if (!context->create())
+ qFatal("EGLFS: Failed to create compositing context");
screen->setRootContext(context);
screen->setRootWindow(this);
}
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp
index c8d5440999..dc918657b4 100644
--- a/src/widgets/kernel/qwidgetbackingstore.cpp
+++ b/src/widgets/kernel/qwidgetbackingstore.cpp
@@ -736,7 +736,8 @@ QWidgetBackingStore::QWidgetBackingStore(QWidget *topLevel)
dirtyOnScreenWidgets(0),
widgetTextures(0),
fullUpdatePending(0),
- updateRequestSent(0)
+ updateRequestSent(0),
+ textureListWatcher(0)
{
store = tlw->backingStore();
Q_ASSERT(store);
@@ -962,6 +963,25 @@ static void findTextureWidgetsRecursively(QWidget *tlw, QWidget *widget, QPlatfo
}
#endif
+QPlatformTextureListWatcher::QPlatformTextureListWatcher(QWidgetBackingStore *backingStore)
+ : m_locked(false),
+ m_backingStore(backingStore)
+{
+}
+
+void QPlatformTextureListWatcher::watch(QPlatformTextureList *textureList)
+{
+ connect(textureList, SIGNAL(locked(bool)), SLOT(onLockStatusChanged(bool)));
+ m_locked = textureList->isLocked();
+}
+
+void QPlatformTextureListWatcher::onLockStatusChanged(bool locked)
+{
+ m_locked = locked;
+ if (!locked)
+ m_backingStore->sync();
+}
+
/*!
Synchronizes the backing store, i.e. dirty areas are repainted and flushed.
*/
@@ -985,6 +1005,17 @@ void QWidgetBackingStore::sync()
return;
}
+ if (textureListWatcher && !textureListWatcher->isLocked()) {
+ textureListWatcher->deleteLater();
+ textureListWatcher = 0;
+ } else if (widgetTextures && widgetTextures->isLocked()) {
+ if (!textureListWatcher)
+ textureListWatcher = new QPlatformTextureListWatcher(this);
+ if (!textureListWatcher->isLocked())
+ textureListWatcher->watch(widgetTextures);
+ return;
+ }
+
doSync();
}
@@ -1077,7 +1108,7 @@ void QWidgetBackingStore::doSync()
delete widgetTextures;
widgetTextures = 0;
if (tlw->d_func()->textureChildSeen) {
- widgetTextures = new QPlatformTextureList; // TODO: implement support for locking
+ widgetTextures = new QPlatformTextureList;
findTextureWidgetsRecursively(tlw, tlw, widgetTextures);
}
fullUpdatePending = false;
diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h
index c6f6541e1f..2fe58fa4a7 100644
--- a/src/widgets/kernel/qwidgetbackingstore_p.h
+++ b/src/widgets/kernel/qwidgetbackingstore_p.h
@@ -61,6 +61,7 @@
QT_BEGIN_NAMESPACE
class QPlatformTextureList;
+class QWidgetBackingStore;
struct BeginPaintInfo {
inline BeginPaintInfo() : wasFlushed(0), nothingToPaint(0), backingStoreRecreated(0) {}
@@ -69,6 +70,23 @@ struct BeginPaintInfo {
uint backingStoreRecreated : 1;
};
+class QPlatformTextureListWatcher : public QObject
+{
+ Q_OBJECT
+
+public:
+ QPlatformTextureListWatcher(QWidgetBackingStore *backingStore);
+ void watch(QPlatformTextureList *textureList);
+ bool isLocked() const { return m_locked; }
+
+private slots:
+ void onLockStatusChanged(bool locked);
+
+private:
+ bool m_locked;
+ QWidgetBackingStore *m_backingStore;
+};
+
class Q_AUTOTEST_EXPORT QWidgetBackingStore
{
public:
@@ -111,6 +129,8 @@ private:
QPoint tlwOffset;
+ QPlatformTextureListWatcher *textureListWatcher;
+
void sendUpdateRequest(QWidget *widget, bool updateImmediately);
static bool flushPaint(QWidget *widget, const QRegion &rgn);
diff --git a/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp b/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp
index 09e0dd5419..5752326911 100644
--- a/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp
+++ b/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp
@@ -58,8 +58,6 @@
#include <QtCore/qmath.h>
#include <qopengl.h>
-#include <GL/glext.h>
-
class OpenGLWidgetPrivate
{
public: