QOpenGLWidget and new-style compositing on eglfs
Integrate with QOpenGLTextureBlitter, QOpenGLWidget and friends. Change-Id: Ic2867b713a21a3d2820d546174fc9164b3dd220c Reviewed-by: Lars Knoll <lars.knoll@digia.com> Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com> Reviewed-by: Paul Olav Tvete <paul.tvete@digia.com>
This commit is contained in:
parent
5b422304a9
commit
ff11af4fbc
@ -156,6 +156,12 @@ void QPlatformTextureList::appendTexture(GLuint textureId, const QRect &geometry
|
|||||||
bi.rect = geometry;
|
bi.rect = geometry;
|
||||||
d->textures.append(bi);
|
d->textures.append(bi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QPlatformTextureList::clear()
|
||||||
|
{
|
||||||
|
Q_D(QPlatformTextureList);
|
||||||
|
d->textures.clear();
|
||||||
|
}
|
||||||
#endif // QT_NO_OPENGL
|
#endif // QT_NO_OPENGL
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -81,12 +81,14 @@ public:
|
|||||||
~QPlatformTextureList();
|
~QPlatformTextureList();
|
||||||
|
|
||||||
int count() const;
|
int count() const;
|
||||||
|
bool isEmpty() const { return count() == 0; }
|
||||||
GLuint textureId(int index) const;
|
GLuint textureId(int index) const;
|
||||||
QRect geometry(int index) const;
|
QRect geometry(int index) const;
|
||||||
void lock(bool on);
|
void lock(bool on);
|
||||||
bool isLocked() const;
|
bool isLocked() const;
|
||||||
|
|
||||||
void appendTexture(GLuint textureId, const QRect &geometry);
|
void appendTexture(GLuint textureId, const QRect &geometry);
|
||||||
|
void clear();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void locked(bool);
|
void locked(bool);
|
||||||
|
@ -42,6 +42,8 @@
|
|||||||
#include <QtGui/QOpenGLContext>
|
#include <QtGui/QOpenGLContext>
|
||||||
#include <QtGui/QOpenGLShaderProgram>
|
#include <QtGui/QOpenGLShaderProgram>
|
||||||
#include <QtGui/QOpenGLFramebufferObject>
|
#include <QtGui/QOpenGLFramebufferObject>
|
||||||
|
#include <QtGui/private/qopengltextureblitter_p.h>
|
||||||
|
#include <qpa/qplatformbackingstore.h>
|
||||||
|
|
||||||
#include "qeglcompositor_p.h"
|
#include "qeglcompositor_p.h"
|
||||||
#include "qeglplatformwindow_p.h"
|
#include "qeglplatformwindow_p.h"
|
||||||
@ -54,7 +56,7 @@ static QEGLCompositor *compositor = 0;
|
|||||||
QEGLCompositor::QEGLCompositor()
|
QEGLCompositor::QEGLCompositor()
|
||||||
: m_context(0),
|
: m_context(0),
|
||||||
m_window(0),
|
m_window(0),
|
||||||
m_program(0)
|
m_blitter(0)
|
||||||
{
|
{
|
||||||
Q_ASSERT(!compositor);
|
Q_ASSERT(!compositor);
|
||||||
m_updateTimer.setSingleShot(true);
|
m_updateTimer.setSingleShot(true);
|
||||||
@ -65,7 +67,10 @@ QEGLCompositor::QEGLCompositor()
|
|||||||
QEGLCompositor::~QEGLCompositor()
|
QEGLCompositor::~QEGLCompositor()
|
||||||
{
|
{
|
||||||
Q_ASSERT(compositor == this);
|
Q_ASSERT(compositor == this);
|
||||||
delete m_program;
|
if (m_blitter) {
|
||||||
|
m_blitter->destroy();
|
||||||
|
delete m_blitter;
|
||||||
|
}
|
||||||
compositor = 0;
|
compositor = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,102 +86,53 @@ void QEGLCompositor::renderAll()
|
|||||||
{
|
{
|
||||||
Q_ASSERT(m_context && m_window);
|
Q_ASSERT(m_context && m_window);
|
||||||
m_context->makeCurrent(m_window->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());
|
QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
|
||||||
QList<QEGLPlatformWindow *> windows = screen->windows();
|
QList<QEGLPlatformWindow *> windows = screen->windows();
|
||||||
for (int i = 0; i < windows.size(); ++i) {
|
for (int i = 0; i < windows.size(); ++i)
|
||||||
QEGLPlatformWindow *window = windows.at(i);
|
render(windows.at(i));
|
||||||
uint texture = window->texture();
|
|
||||||
if (texture)
|
|
||||||
render(window, texture, window->isRaster());
|
|
||||||
}
|
|
||||||
|
|
||||||
m_program->release();
|
m_blitter->release();
|
||||||
m_context->swapBuffers(m_window->window());
|
m_context->swapBuffers(m_window->window());
|
||||||
|
|
||||||
|
for (int i = 0; i < windows.size(); ++i)
|
||||||
|
windows.at(i)->composited();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QEGLCompositor::ensureProgram()
|
void QEGLCompositor::render(QEGLPlatformWindow *window)
|
||||||
{
|
{
|
||||||
if (!m_program) {
|
const QPlatformTextureList *textures = window->textures();
|
||||||
static const char *textureVertexProgram =
|
if (!textures)
|
||||||
"attribute highp vec2 vertexCoordEntry;\n"
|
return;
|
||||||
"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 =
|
const QRect targetWindowRect(QPoint(0, 0), window->screen()->geometry().size());
|
||||||
"uniform sampler2D texture;\n"
|
glViewport(0, 0, targetWindowRect.width(), targetWindowRect.height());
|
||||||
"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;
|
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());
|
||||||
|
|
||||||
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
|
if (textures->count() > 1 && i == textures->count() - 1) {
|
||||||
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
|
glEnable(GL_BLEND);
|
||||||
m_program->link();
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
|
||||||
m_vertexCoordEntry = m_program->attributeLocation("vertexCoordEntry");
|
glDisable(GL_BLEND);
|
||||||
m_textureCoordEntry = m_program->attributeLocation("textureCoordEntry");
|
} else if (textures->count() == 1) {
|
||||||
m_isRasterEntry = m_program->uniformLocation("isRaster");
|
m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
|
||||||
|
} else {
|
||||||
|
m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QEGLCompositor::render(QEGLPlatformWindow *window, uint texture, bool raster)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QEGLCompositor *QEGLCompositor::instance()
|
QEGLCompositor *QEGLCompositor::instance()
|
||||||
|
@ -46,8 +46,8 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QOpenGLShaderProgram;
|
|
||||||
class QOpenGLContext;
|
class QOpenGLContext;
|
||||||
|
class QOpenGLTextureBlitter;
|
||||||
class QEGLPlatformWindow;
|
class QEGLPlatformWindow;
|
||||||
|
|
||||||
class QEGLCompositor : public QObject
|
class QEGLCompositor : public QObject
|
||||||
@ -67,16 +67,12 @@ private:
|
|||||||
QEGLCompositor();
|
QEGLCompositor();
|
||||||
~QEGLCompositor();
|
~QEGLCompositor();
|
||||||
|
|
||||||
void render(QEGLPlatformWindow *window, uint texture, bool raster);
|
void render(QEGLPlatformWindow *window);
|
||||||
void ensureProgram();
|
|
||||||
|
|
||||||
QOpenGLContext *m_context;
|
QOpenGLContext *m_context;
|
||||||
QEGLPlatformWindow *m_window;
|
QEGLPlatformWindow *m_window;
|
||||||
QTimer m_updateTimer;
|
QTimer m_updateTimer;
|
||||||
QOpenGLShaderProgram *m_program;
|
QOpenGLTextureBlitter *m_blitter;
|
||||||
int m_vertexCoordEntry;
|
|
||||||
int m_textureCoordEntry;
|
|
||||||
int m_isRasterEntry;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -76,11 +76,18 @@ QT_BEGIN_NAMESPACE
|
|||||||
QEGLPlatformBackingStore::QEGLPlatformBackingStore(QWindow *window)
|
QEGLPlatformBackingStore::QEGLPlatformBackingStore(QWindow *window)
|
||||||
: QPlatformBackingStore(window),
|
: QPlatformBackingStore(window),
|
||||||
m_window(static_cast<QEGLPlatformWindow *>(window->handle())),
|
m_window(static_cast<QEGLPlatformWindow *>(window->handle())),
|
||||||
m_texture(0)
|
m_bsTexture(0),
|
||||||
|
m_textures(new QPlatformTextureList),
|
||||||
|
m_lockedWidgetTextures(0)
|
||||||
{
|
{
|
||||||
m_window->setBackingStore(this);
|
m_window->setBackingStore(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QEGLPlatformBackingStore::~QEGLPlatformBackingStore()
|
||||||
|
{
|
||||||
|
delete m_textures;
|
||||||
|
}
|
||||||
|
|
||||||
QPaintDevice *QEGLPlatformBackingStore::paintDevice()
|
QPaintDevice *QEGLPlatformBackingStore::paintDevice()
|
||||||
{
|
{
|
||||||
return &m_image;
|
return &m_image;
|
||||||
@ -88,7 +95,18 @@ QPaintDevice *QEGLPlatformBackingStore::paintDevice()
|
|||||||
|
|
||||||
void QEGLPlatformBackingStore::updateTexture()
|
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()) {
|
if (!m_dirty.isNull()) {
|
||||||
QRegion fixed;
|
QRegion fixed;
|
||||||
@ -126,24 +144,56 @@ void QEGLPlatformBackingStore::updateTexture()
|
|||||||
|
|
||||||
void QEGLPlatformBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset)
|
void QEGLPlatformBackingStore::flush(QWindow *window, const QRegion ®ion, 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(region);
|
||||||
Q_UNUSED(offset);
|
Q_UNUSED(offset);
|
||||||
|
|
||||||
#ifdef QEGL_EXTRA_DEBUG
|
|
||||||
qWarning("QEglBackingStore::flush %p", window);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
|
QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
|
||||||
QEGLPlatformWindow *dstWin = screen->compositingWindow();
|
QEGLPlatformWindow *dstWin = screen->compositingWindow();
|
||||||
if (!dstWin || !dstWin->isRaster())
|
if (!dstWin || !dstWin->isRaster())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_window->create();
|
screen->compositingContext()->makeCurrent(dstWin->window());
|
||||||
QOpenGLContext *context = screen->compositingContext();
|
|
||||||
context->makeCurrent(dstWin->window());
|
|
||||||
updateTexture();
|
updateTexture();
|
||||||
composite(context, dstWin);
|
m_textures->clear();
|
||||||
|
m_textures->appendTexture(m_bsTexture, window->geometry());
|
||||||
|
composite(screen->compositingContext(), dstWin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QEGLPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, 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;
|
||||||
|
|
||||||
|
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();
|
||||||
|
m_textures->appendTexture(m_bsTexture, window->geometry());
|
||||||
|
|
||||||
|
textures->lock(true);
|
||||||
|
m_lockedWidgetTextures = textures;
|
||||||
|
|
||||||
|
composite(screen->compositingContext(), dstWin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QEGLPlatformBackingStore::composite(QOpenGLContext *context, QEGLPlatformWindow *window)
|
void QEGLPlatformBackingStore::composite(QOpenGLContext *context, QEGLPlatformWindow *window)
|
||||||
@ -151,6 +201,15 @@ void QEGLPlatformBackingStore::composite(QOpenGLContext *context, QEGLPlatformWi
|
|||||||
QEGLCompositor::instance()->schedule(context, window);
|
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)
|
void QEGLPlatformBackingStore::beginPaint(const QRegion &rgn)
|
||||||
{
|
{
|
||||||
m_dirty |= 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());
|
QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
|
||||||
QEGLPlatformWindow *dstWin = screen->compositingWindow();
|
QEGLPlatformWindow *dstWin = screen->compositingWindow();
|
||||||
if (!dstWin || !dstWin->isRaster())
|
if (!dstWin || (!dstWin->isRaster() && dstWin->window()->surfaceType() != QSurface::RasterGLSurface))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_image = QImage(size, QImage::Format_RGB32);
|
m_image = QImage(size, QImage::Format_RGB32);
|
||||||
m_window->create();
|
m_window->create();
|
||||||
|
|
||||||
screen->compositingContext()->makeCurrent(dstWin->window());
|
screen->compositingContext()->makeCurrent(dstWin->window());
|
||||||
|
if (m_bsTexture) {
|
||||||
|
glDeleteTextures(1, &m_bsTexture);
|
||||||
|
m_bsTexture = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_texture)
|
QImage QEGLPlatformBackingStore::toImage() const
|
||||||
glDeleteTextures(1, &m_texture);
|
{
|
||||||
|
return m_image;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -50,31 +50,41 @@
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QOpenGLContext;
|
class QOpenGLContext;
|
||||||
|
class QPlatformTextureList;
|
||||||
class QEGLPlatformWindow;
|
class QEGLPlatformWindow;
|
||||||
|
|
||||||
class QEGLPlatformBackingStore : public QPlatformBackingStore
|
class QEGLPlatformBackingStore : public QPlatformBackingStore
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QEGLPlatformBackingStore(QWindow *window);
|
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 ®ion, const QPoint &offset);
|
void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE;
|
||||||
void resize(const QSize &size, const QRegion &staticContents);
|
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 ®ion, const QPoint &offset,
|
||||||
|
QPlatformTextureList *textures, QOpenGLContext *context) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
const QPlatformTextureList *textures() const { return m_textures; }
|
||||||
|
|
||||||
virtual void composite(QOpenGLContext *context, QEGLPlatformWindow *window);
|
virtual void composite(QOpenGLContext *context, QEGLPlatformWindow *window);
|
||||||
|
|
||||||
|
void composited();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateTexture();
|
void updateTexture();
|
||||||
|
|
||||||
QEGLPlatformWindow *m_window;
|
QEGLPlatformWindow *m_window;
|
||||||
QImage m_image;
|
QImage m_image;
|
||||||
uint m_texture;
|
|
||||||
QRegion m_dirty;
|
QRegion m_dirty;
|
||||||
|
uint m_bsTexture;
|
||||||
|
QPlatformTextureList *m_textures;
|
||||||
|
QPlatformTextureList *m_lockedWidgetTextures;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -127,11 +127,8 @@ void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLCont
|
|||||||
|
|
||||||
bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
|
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);
|
bindApi(m_format);
|
||||||
|
|
||||||
EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface);
|
EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface);
|
||||||
@ -192,9 +189,6 @@ bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
|
|||||||
|
|
||||||
QEGLPlatformContext::~QEGLPlatformContext()
|
QEGLPlatformContext::~QEGLPlatformContext()
|
||||||
{
|
{
|
||||||
#ifdef QEGL_EXTRA_DEBUG
|
|
||||||
qWarning("QEglContext::~QEglContext(): %p\n",this);
|
|
||||||
#endif
|
|
||||||
if (m_eglContext != EGL_NO_CONTEXT) {
|
if (m_eglContext != EGL_NO_CONTEXT) {
|
||||||
eglDestroyContext(m_eglDisplay, m_eglContext);
|
eglDestroyContext(m_eglDisplay, m_eglContext);
|
||||||
m_eglContext = EGL_NO_CONTEXT;
|
m_eglContext = EGL_NO_CONTEXT;
|
||||||
@ -203,9 +197,6 @@ QEGLPlatformContext::~QEGLPlatformContext()
|
|||||||
|
|
||||||
void QEGLPlatformContext::doneCurrent()
|
void QEGLPlatformContext::doneCurrent()
|
||||||
{
|
{
|
||||||
#ifdef QEGL_EXTRA_DEBUG
|
|
||||||
qWarning("QEglContext::doneCurrent:%p\n",this);
|
|
||||||
#endif
|
|
||||||
bindApi(m_format);
|
bindApi(m_format);
|
||||||
bool ok = eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
bool ok = eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
@ -214,9 +205,6 @@ void QEGLPlatformContext::doneCurrent()
|
|||||||
|
|
||||||
void QEGLPlatformContext::swapBuffers(QPlatformSurface *surface)
|
void QEGLPlatformContext::swapBuffers(QPlatformSurface *surface)
|
||||||
{
|
{
|
||||||
#ifdef QEGL_EXTRA_DEBUG
|
|
||||||
qWarning("QEglContext::swapBuffers:%p\n",this);
|
|
||||||
#endif
|
|
||||||
bindApi(m_format);
|
bindApi(m_format);
|
||||||
EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface);
|
EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface);
|
||||||
bool ok = eglSwapBuffers(m_eglDisplay, eglSurface);
|
bool ok = eglSwapBuffers(m_eglDisplay, eglSurface);
|
||||||
@ -226,9 +214,6 @@ void QEGLPlatformContext::swapBuffers(QPlatformSurface *surface)
|
|||||||
|
|
||||||
void (*QEGLPlatformContext::getProcAddress(const QByteArray &procName)) ()
|
void (*QEGLPlatformContext::getProcAddress(const QByteArray &procName)) ()
|
||||||
{
|
{
|
||||||
#ifdef QEGL_EXTRA_DEBUG
|
|
||||||
qWarning("QEglContext::getProcAddress%p\n",this);
|
|
||||||
#endif
|
|
||||||
bindApi(m_format);
|
bindApi(m_format);
|
||||||
return eglGetProcAddress(procName.constData());
|
return eglGetProcAddress(procName.constData());
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
#include <QtGui/QWindow>
|
#include <QtGui/QWindow>
|
||||||
#include <QtGui/QOpenGLContext>
|
#include <QtGui/QOpenGLContext>
|
||||||
|
#include <QtGui/QOffscreenSurface>
|
||||||
#include <QtGui/QGuiApplication>
|
#include <QtGui/QGuiApplication>
|
||||||
#include <qpa/qwindowsysteminterface.h>
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
#include <qpa/qplatforminputcontextfactory_p.h>
|
#include <qpa/qplatforminputcontextfactory_p.h>
|
||||||
@ -79,8 +80,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
The backing store, native interface accessors, font database,
|
The backing store, native interface accessors, font database,
|
||||||
basic capability flags, etc. are provided out of the box, no
|
basic capability flags, etc. are provided out of the box, no
|
||||||
further customization is needed. Subclasses are still responsible
|
further customization is needed.
|
||||||
however for context and offscreen surface creation.
|
|
||||||
|
|
||||||
\note It is critical that this class' implementation of
|
\note It is critical that this class' implementation of
|
||||||
initialize() is called. Therefore subclasses should either avoid
|
initialize() is called. Therefore subclasses should either avoid
|
||||||
@ -155,6 +155,23 @@ QPlatformWindow *QEGLPlatformIntegration::createPlatformWindow(QWindow *window)
|
|||||||
return w;
|
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
|
bool QEGLPlatformIntegration::hasCapability(QPlatformIntegration::Capability cap) const
|
||||||
{
|
{
|
||||||
switch (cap) {
|
switch (cap) {
|
||||||
@ -162,6 +179,7 @@ bool QEGLPlatformIntegration::hasCapability(QPlatformIntegration::Capability cap
|
|||||||
case OpenGL: return true;
|
case OpenGL: return true;
|
||||||
case ThreadedOpenGL: return true;
|
case ThreadedOpenGL: return true;
|
||||||
case WindowManagement: return false;
|
case WindowManagement: return false;
|
||||||
|
case RasterGLSurface: return true;
|
||||||
default: return QPlatformIntegration::hasCapability(cap);
|
default: return QPlatformIntegration::hasCapability(cap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
class QEGLPlatformScreen;
|
class QEGLPlatformScreen;
|
||||||
class QEGLPlatformWindow;
|
class QEGLPlatformWindow;
|
||||||
|
class QEGLPlatformContext;
|
||||||
class QFbVtHandler;
|
class QFbVtHandler;
|
||||||
|
|
||||||
class QEGLPlatformIntegration : public QPlatformIntegration, public QPlatformNativeInterface
|
class QEGLPlatformIntegration : public QPlatformIntegration, public QPlatformNativeInterface
|
||||||
@ -70,6 +71,8 @@ public:
|
|||||||
|
|
||||||
QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
|
QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
|
||||||
QPlatformBackingStore *createPlatformBackingStore(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;
|
bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
@ -83,6 +86,13 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
virtual QEGLPlatformScreen *createScreen() const = 0;
|
virtual QEGLPlatformScreen *createScreen() const = 0;
|
||||||
virtual QEGLPlatformWindow *createWindow(QWindow *window) 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; }
|
virtual EGLNativeDisplayType nativeDisplay() const { return EGL_DEFAULT_DISPLAY; }
|
||||||
|
|
||||||
void createInputHandlers();
|
void createInputHandlers();
|
||||||
|
@ -92,6 +92,7 @@ void QEGLPlatformWindow::create()
|
|||||||
|
|
||||||
// Save the original surface type before changing to OpenGLSurface.
|
// Save the original surface type before changing to OpenGLSurface.
|
||||||
m_raster = (window()->surfaceType() == QSurface::RasterSurface);
|
m_raster = (window()->surfaceType() == QSurface::RasterSurface);
|
||||||
|
if (m_raster) // change to OpenGL, but not for RasterGLSurface
|
||||||
window()->setSurfaceType(QSurface::OpenGLSurface);
|
window()->setSurfaceType(QSurface::OpenGLSurface);
|
||||||
|
|
||||||
if (window()->type() == Qt::Desktop) {
|
if (window()->type() == Qt::Desktop) {
|
||||||
@ -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)
|
if (m_backingStore)
|
||||||
return m_backingStore->texture();
|
return m_backingStore->textures();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QEGLPlatformWindow::composited()
|
||||||
|
{
|
||||||
|
if (m_backingStore)
|
||||||
|
m_backingStore->composited();
|
||||||
|
}
|
||||||
|
|
||||||
WId QEGLPlatformWindow::winId() const
|
WId QEGLPlatformWindow::winId() const
|
||||||
{
|
{
|
||||||
return m_winId;
|
return m_winId;
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QEGLPlatformBackingStore;
|
class QEGLPlatformBackingStore;
|
||||||
|
class QPlatformTextureList;
|
||||||
|
|
||||||
class QEGLPlatformWindow : public QPlatformWindow
|
class QEGLPlatformWindow : public QPlatformWindow
|
||||||
{
|
{
|
||||||
@ -58,8 +59,9 @@ public:
|
|||||||
|
|
||||||
QEGLPlatformBackingStore *backingStore() { return m_backingStore; }
|
QEGLPlatformBackingStore *backingStore() { return m_backingStore; }
|
||||||
void setBackingStore(QEGLPlatformBackingStore *backingStore) { m_backingStore = backingStore; }
|
void setBackingStore(QEGLPlatformBackingStore *backingStore) { m_backingStore = backingStore; }
|
||||||
uint texture() const;
|
const QPlatformTextureList *textures() const;
|
||||||
bool isRaster() const { return m_raster; }
|
void composited();
|
||||||
|
bool isRaster() const;
|
||||||
|
|
||||||
WId winId() const Q_DECL_OVERRIDE;
|
WId winId() const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
QT += core-private gui-private platformsupport-private
|
QT += core-private gui-private platformsupport-private
|
||||||
|
|
||||||
#DEFINES += QEGL_EXTRA_DEBUG
|
|
||||||
|
|
||||||
# Avoid X11 header collision
|
# Avoid X11 header collision
|
||||||
DEFINES += MESA_EGL_NO_X11_HEADERS
|
DEFINES += MESA_EGL_NO_X11_HEADERS
|
||||||
|
|
||||||
|
@ -88,17 +88,6 @@ bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
|
|||||||
return QEGLPlatformIntegration::hasCapability(cap);
|
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()
|
void QEglFSIntegration::initialize()
|
||||||
{
|
{
|
||||||
QEglFSHooks::hooks()->platformInit();
|
QEglFSHooks::hooks()->platformInit();
|
||||||
@ -124,6 +113,20 @@ QEGLPlatformWindow *QEglFSIntegration::createWindow(QWindow *window) const
|
|||||||
return new QEglFSWindow(window);
|
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
|
QVariant QEglFSIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
|
||||||
{
|
{
|
||||||
switch (hint)
|
switch (hint)
|
||||||
|
@ -54,9 +54,6 @@ public:
|
|||||||
QEglFSIntegration();
|
QEglFSIntegration();
|
||||||
~QEglFSIntegration();
|
~QEglFSIntegration();
|
||||||
|
|
||||||
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
|
|
||||||
QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
|
|
||||||
|
|
||||||
void initialize() Q_DECL_OVERRIDE;
|
void initialize() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
|
bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
|
||||||
@ -67,6 +64,12 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
QEGLPlatformScreen *createScreen() const Q_DECL_OVERRIDE;
|
QEGLPlatformScreen *createScreen() const Q_DECL_OVERRIDE;
|
||||||
QEGLPlatformWindow *createWindow(QWindow *window) 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;
|
EGLNativeDisplayType nativeDisplay() const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -53,10 +53,6 @@ QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
|
|||||||
m_rootWindow(0),
|
m_rootWindow(0),
|
||||||
m_rootContext(0)
|
m_rootContext(0)
|
||||||
{
|
{
|
||||||
#ifdef QEGL_EXTRA_DEBUG
|
|
||||||
qWarning("QEglScreen %p\n", this);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_cursor = QEglFSHooks::hooks()->createCursor(this);
|
m_cursor = QEglFSHooks::hooks()->createCursor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,9 +58,6 @@ QEglFSWindow::QEglFSWindow(QWindow *w)
|
|||||||
, m_window(0)
|
, m_window(0)
|
||||||
, m_flags(0)
|
, m_flags(0)
|
||||||
{
|
{
|
||||||
#ifdef QEGL_EXTRA_DEBUG
|
|
||||||
qWarning("QEglWindow %p: %p 0x%x\n", this, w, uint(m_window));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QEglFSWindow::~QEglFSWindow()
|
QEglFSWindow::~QEglFSWindow()
|
||||||
@ -114,7 +111,8 @@ void QEglFSWindow::create()
|
|||||||
QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance());
|
QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance());
|
||||||
context->setFormat(window()->requestedFormat());
|
context->setFormat(window()->requestedFormat());
|
||||||
context->setScreen(window()->screen());
|
context->setScreen(window()->screen());
|
||||||
context->create();
|
if (!context->create())
|
||||||
|
qFatal("EGLFS: Failed to create compositing context");
|
||||||
screen->setRootContext(context);
|
screen->setRootContext(context);
|
||||||
screen->setRootWindow(this);
|
screen->setRootWindow(this);
|
||||||
}
|
}
|
||||||
|
@ -736,7 +736,8 @@ QWidgetBackingStore::QWidgetBackingStore(QWidget *topLevel)
|
|||||||
dirtyOnScreenWidgets(0),
|
dirtyOnScreenWidgets(0),
|
||||||
widgetTextures(0),
|
widgetTextures(0),
|
||||||
fullUpdatePending(0),
|
fullUpdatePending(0),
|
||||||
updateRequestSent(0)
|
updateRequestSent(0),
|
||||||
|
textureListWatcher(0)
|
||||||
{
|
{
|
||||||
store = tlw->backingStore();
|
store = tlw->backingStore();
|
||||||
Q_ASSERT(store);
|
Q_ASSERT(store);
|
||||||
@ -962,6 +963,25 @@ static void findTextureWidgetsRecursively(QWidget *tlw, QWidget *widget, QPlatfo
|
|||||||
}
|
}
|
||||||
#endif
|
#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.
|
Synchronizes the backing store, i.e. dirty areas are repainted and flushed.
|
||||||
*/
|
*/
|
||||||
@ -985,6 +1005,17 @@ void QWidgetBackingStore::sync()
|
|||||||
return;
|
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();
|
doSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1077,7 +1108,7 @@ void QWidgetBackingStore::doSync()
|
|||||||
delete widgetTextures;
|
delete widgetTextures;
|
||||||
widgetTextures = 0;
|
widgetTextures = 0;
|
||||||
if (tlw->d_func()->textureChildSeen) {
|
if (tlw->d_func()->textureChildSeen) {
|
||||||
widgetTextures = new QPlatformTextureList; // TODO: implement support for locking
|
widgetTextures = new QPlatformTextureList;
|
||||||
findTextureWidgetsRecursively(tlw, tlw, widgetTextures);
|
findTextureWidgetsRecursively(tlw, tlw, widgetTextures);
|
||||||
}
|
}
|
||||||
fullUpdatePending = false;
|
fullUpdatePending = false;
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QPlatformTextureList;
|
class QPlatformTextureList;
|
||||||
|
class QWidgetBackingStore;
|
||||||
|
|
||||||
struct BeginPaintInfo {
|
struct BeginPaintInfo {
|
||||||
inline BeginPaintInfo() : wasFlushed(0), nothingToPaint(0), backingStoreRecreated(0) {}
|
inline BeginPaintInfo() : wasFlushed(0), nothingToPaint(0), backingStoreRecreated(0) {}
|
||||||
@ -69,6 +70,23 @@ struct BeginPaintInfo {
|
|||||||
uint backingStoreRecreated : 1;
|
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
|
class Q_AUTOTEST_EXPORT QWidgetBackingStore
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -111,6 +129,8 @@ private:
|
|||||||
|
|
||||||
QPoint tlwOffset;
|
QPoint tlwOffset;
|
||||||
|
|
||||||
|
QPlatformTextureListWatcher *textureListWatcher;
|
||||||
|
|
||||||
void sendUpdateRequest(QWidget *widget, bool updateImmediately);
|
void sendUpdateRequest(QWidget *widget, bool updateImmediately);
|
||||||
|
|
||||||
static bool flushPaint(QWidget *widget, const QRegion &rgn);
|
static bool flushPaint(QWidget *widget, const QRegion &rgn);
|
||||||
|
@ -58,8 +58,6 @@
|
|||||||
#include <QtCore/qmath.h>
|
#include <QtCore/qmath.h>
|
||||||
#include <qopengl.h>
|
#include <qopengl.h>
|
||||||
|
|
||||||
#include <GL/glext.h>
|
|
||||||
|
|
||||||
class OpenGLWidgetPrivate
|
class OpenGLWidgetPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user