summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJørgen Lind <jorgen.lind@nokia.com>2010-11-23 14:34:09 (GMT)
committerJørgen Lind <jorgen.lind@nokia.com>2010-11-24 08:54:48 (GMT)
commit004cd14b84e3683cd92cf01061ee9688990f990c (patch)
tree8f879f07439b212de831c528e832d3c3ab4c6bb3
parentf309a20b4177572282082b8c17ec9025b75a69b1 (diff)
downloadQt-004cd14b84e3683cd92cf01061ee9688990f990c.zip
Qt-004cd14b84e3683cd92cf01061ee9688990f990c.tar.gz
Qt-004cd14b84e3683cd92cf01061ee9688990f990c.tar.bz2
Lighthouse: Fix QGLContext::currentContext for systems with limited
resources. The example plugins EGLFS uses only 1 native context. Make sure that we only use this 1 context, and that we dont wrap it in many different QPlatformGLContexts or QGLContexts instanses. This change also removes the QPlatformWindow link which was made in the initial QPlatformGLContext change. Lighthouse has to support situations where a context isnt bound to a QPlatformWindow. Reviewed-by: gunnar
-rw-r--r--src/gui/kernel/qplatformglcontext_qpa.cpp18
-rw-r--r--src/gui/kernel/qplatformglcontext_qpa.h4
-rw-r--r--src/opengl/qgl.cpp58
-rw-r--r--src/opengl/qgl.h5
-rw-r--r--src/opengl/qgl_qpa.cpp20
-rw-r--r--src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp4
-rw-r--r--src/plugins/platforms/eglconvenience/qeglplatformcontext.h2
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp72
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h11
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindowsurface.cpp5
-rw-r--r--src/plugins/platforms/testlite/qglxintegration.cpp6
-rw-r--r--src/plugins/platforms/testlite/qglxintegration.h2
-rw-r--r--src/plugins/platforms/testlite/qtestlitewindow.cpp2
13 files changed, 141 insertions, 68 deletions
diff --git a/src/gui/kernel/qplatformglcontext_qpa.cpp b/src/gui/kernel/qplatformglcontext_qpa.cpp
index a450b33..5d2faf1 100644
--- a/src/gui/kernel/qplatformglcontext_qpa.cpp
+++ b/src/gui/kernel/qplatformglcontext_qpa.cpp
@@ -61,8 +61,8 @@ static QThreadStorage<QPlatformGLThreadContext *> qplatformgl_context_storage;
class QPlatformGLContextPrivate
{
public:
- QPlatformGLContextPrivate(QPlatformWindow *platformWindow)
- :qGLContextHandle(0),platformWindow(platformWindow)
+ QPlatformGLContextPrivate()
+ :qGLContextHandle(0)
{
}
@@ -73,7 +73,6 @@ public:
}
void *qGLContextHandle;
void (*qGLContextDeleteFunction)(void *handle);
- QPlatformWindow *platformWindow;
static QPlatformGLContext *staticSharedContext;
static void setCurrentContext(QPlatformGLContext *context);
@@ -96,15 +95,6 @@ void QPlatformGLContextPrivate::setCurrentContext(QPlatformGLContext *context)
}
/*!
- Returns the platformWindow which this QPlatformGLContext belongs to.
-*/
-QPlatformWindow *QPlatformGLContext::platformWindow() const
-{
- Q_D(const QPlatformGLContext);
- return d->platformWindow;
-}
-
-/*!
Returns the last context which called makeCurrent. This function is thread aware.
*/
const QPlatformGLContext* QPlatformGLContext::currentContext()
@@ -119,8 +109,8 @@ const QPlatformGLContext* QPlatformGLContext::currentContext()
/*!
All subclasses needs to specify the platformWindow. It can be a null window.
*/
-QPlatformGLContext::QPlatformGLContext(QPlatformWindow *platformWindow)
- :d_ptr(new QPlatformGLContextPrivate(platformWindow))
+QPlatformGLContext::QPlatformGLContext()
+ :d_ptr(new QPlatformGLContextPrivate())
{
}
diff --git a/src/gui/kernel/qplatformglcontext_qpa.h b/src/gui/kernel/qplatformglcontext_qpa.h
index 3e10c2b..a70e046 100644
--- a/src/gui/kernel/qplatformglcontext_qpa.h
+++ b/src/gui/kernel/qplatformglcontext_qpa.h
@@ -58,7 +58,7 @@ class Q_OPENGL_EXPORT QPlatformGLContext
Q_DECLARE_PRIVATE(QPlatformGLContext);
public:
- explicit QPlatformGLContext(QPlatformWindow *platformWindow);
+ explicit QPlatformGLContext();
virtual ~QPlatformGLContext();
virtual void makeCurrent();
@@ -68,8 +68,6 @@ public:
virtual QPlatformWindowFormat platformWindowFormat() const = 0;
- QPlatformWindow *platformWindow() const;
-
const static QPlatformGLContext *currentContext();
const static QPlatformGLContext *defaultSharedContext();
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 65d3bbe..5eb4c16 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -2095,6 +2095,14 @@ QGLContext::QGLContext(const QGLFormat &format)
d->init(0, format);
}
+QGLContext::QGLContext(QPlatformGLContext *platformContext)
+ : d_ptr(new QGLContextPrivate(this))
+{
+ Q_D(QGLContext);
+ d->init(0,QGLFormat::fromPlatformWindowFormat(platformContext->platformWindowFormat()));
+ d->platformContext = platformContext;
+}
+
/*!
Destroys the OpenGL context and frees its resources.
*/
@@ -3152,6 +3160,18 @@ void QGLContext::setDevice(QPaintDevice *pDev)
}
}
+QGLContext *QGLContext::fromPlatformGLContext(QPlatformGLContext *platformContext)
+{
+ if (!platformContext)
+ return 0;
+ if (platformContext->qGLContextHandle()) {
+ return reinterpret_cast<QGLContext *>(platformContext->qGLContextHandle());
+ }
+ QGLContext *glContext = new QGLContext(platformContext);
+ glContext->create();
+ return glContext;
+}
+
/*!
\fn bool QGLContext::isValid() const
@@ -3304,11 +3324,16 @@ bool QGLContext::areSharing(const QGLContext *context1, const QGLContext *contex
bool QGLContext::create(const QGLContext* shareContext)
{
Q_D(QGLContext);
+#ifdef Q_WS_QPA
+ if (!d->paintDevice && !d->platformContext)
+#else
if (!d->paintDevice)
+#endif
return false;
+
reset();
d->valid = chooseContext(shareContext);
- if (d->valid && d->paintDevice->devType() == QInternal::Widget) {
+ if (d->valid && d->paintDevice && d->paintDevice->devType() == QInternal::Widget) {
QWidgetPrivate *wd = qt_widget_private(static_cast<QWidget *>(d->paintDevice));
wd->usesDoubleBufferedGLContext = d->glFormat.doubleBuffer();
}
@@ -3389,14 +3414,7 @@ const QGLContext* QGLContext::currentContext()
{
#ifdef Q_WS_QPA
if (const QPlatformGLContext *threadContext = QPlatformGLContext::currentContext()) {
- if (threadContext->qGLContextHandle()) {
- return (const QGLContext *)threadContext->qGLContextHandle();
- } else {
- QWidget *widget = threadContext->platformWindow()->widget();
- QGLContext *context = new QGLContext(QGLFormat::fromPlatformWindowFormat(threadContext->platformWindowFormat()),widget);
- context->create(); //don't know how to pass in the sharecontext. (doesn't really matter though)
- return context;
- }
+ return QGLContext::fromPlatformGLContext(const_cast<QPlatformGLContext *>(threadContext));
}
return 0;
#else
@@ -3781,7 +3799,18 @@ QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WindowFl
setAttribute(Qt::WA_PaintOnScreen);
setAttribute(Qt::WA_NoSystemBackground);
setAutoFillBackground(true); // for compatibility
+#ifdef Q_WS_QPA
+ setPlatformWindowFormat(QGLFormat::toPlatformWindowFormat(QGLFormat::defaultFormat()));
+ winId(); // create window;
+ QGLContext *glContext = 0;
+ if (platformWindow())
+ glContext = QGLContext::fromPlatformGLContext(platformWindow()->glContext());
+ if (glContext){
+ d->init(glContext,shareWidget);
+ }
+#else
d->init(new QGLContext(QGLFormat::defaultFormat(), this), shareWidget);
+#endif
}
@@ -3821,7 +3850,18 @@ QGLWidget::QGLWidget(const QGLFormat &format, QWidget *parent, const QGLWidget*
setAttribute(Qt::WA_PaintOnScreen);
setAttribute(Qt::WA_NoSystemBackground);
setAutoFillBackground(true); // for compatibility
+#ifdef Q_WS_QPA
+ setPlatformWindowFormat(QGLFormat::toPlatformWindowFormat(QGLFormat::defaultFormat()));
+ winId(); // create window;
+ QGLContext *glContext = 0;
+ if (platformWindow())
+ glContext = QGLContext::fromPlatformGLContext(platformWindow()->glContext());
+ if (glContext){
+ d->init(glContext,shareWidget);
+ }
+#else
d->init(new QGLContext(format, this), shareWidget);
+#endif
}
/*!
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index 1f864a3..f5e0bd7 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -383,6 +383,7 @@ public:
static const QGLContext* currentContext();
+ static QGLContext *fromPlatformGLContext(QPlatformGLContext *platformContext);
protected:
virtual bool chooseContext(const QGLContext* shareContext = 0);
@@ -412,6 +413,10 @@ protected:
static QGLContext* currentCtx;
private:
+#ifdef Q_WS_QPA
+ QGLContext(QPlatformGLContext *platformContext);
+#endif
+
QScopedPointer<QGLContextPrivate> d_ptr;
friend class QGLPixelBuffer;
diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp
index 28bea83..e997704 100644
--- a/src/opengl/qgl_qpa.cpp
+++ b/src/opengl/qgl_qpa.cpp
@@ -129,7 +129,11 @@ void qDeleteQGLContext(void *handle)
bool QGLContext::chooseContext(const QGLContext* shareContext)
{
Q_D(QGLContext);
- if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) {
+ if (d->platformContext && !d->platformContext->qGLContextHandle()) {
+ d->platformContext->setQGLContextHandle(this,qDeleteQGLContext);
+ d->glFormat = QGLFormat::fromPlatformWindowFormat(d->platformContext->platformWindowFormat());
+ d->valid = true;
+ }else if(!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) {
d->valid = false;
}else {
QWidget *widget = static_cast<QWidget *>(d->paintDevice);
@@ -215,10 +219,9 @@ void QGLWidget::setContext(QGLContext *context,
qWarning("QGLWidget::setContext: Cannot set null context");
return;
}
- if (!context->deviceIsPixmap() && context->device() != this) {
- qWarning("QGLWidget::setContext: Context must refer to this widget");
- return;
- }
+
+ if (context->device() == 0) // a context may refere to more than 1 window.
+ context->setDevice(this); //but its better to point to 1 of them than none of them.
QGLContext* oldcx = d->glcx;
d->glcx = context;
@@ -312,11 +315,8 @@ bool QGLWidget::event(QEvent *e)
{
Q_D(QGLWidget);
if (e->type() == QEvent::WinIdChange) {
- if (d->glcx->isValid()) {
- if (QGLContext::currentContext() == d->glcx)
- QGLContextPrivate::setCurrentContext(0); //Its not valid anymore
- setContext(new QGLContext(d->glcx->requestedFormat(), this));
-
+ if (platformWindow()) {
+ d->glcx = QGLContext::fromPlatformGLContext(platformWindow()->glContext());
}
}
return QWidget::event(e);
diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp
index a169c35..c4adb6f 100644
--- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp
+++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.cpp
@@ -48,8 +48,8 @@
#include <EGL/egl.h>
-QEGLPlatformContext::QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi, QPlatformWindow *platformWindow)
- : QPlatformGLContext(platformWindow)
+QEGLPlatformContext::QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi)
+ : QPlatformGLContext()
, m_eglDisplay(display)
, m_eglSurface(surface)
, m_eglApi(eglApi)
diff --git a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h
index 2c38aca..ae1a891 100644
--- a/src/plugins/platforms/eglconvenience/qeglplatformcontext.h
+++ b/src/plugins/platforms/eglconvenience/qeglplatformcontext.h
@@ -48,7 +48,7 @@
class QEGLPlatformContext : public QPlatformGLContext
{
public:
- QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi, QPlatformWindow *platformWindow);
+ QEGLPlatformContext(EGLDisplay display, EGLConfig config, EGLint contextAttrs[], EGLSurface surface, EGLenum eglApi);
~QEGLPlatformContext();
void makeCurrent();
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index b9d1b17..7abc492 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -87,7 +87,10 @@ static struct AttrInfo attrs[] = {
#endif //QEGL_EXTRA_DEBUG
QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display)
- : m_depth(32), m_format(QImage::Format_ARGB32_Premultiplied), m_platformContext(0)
+ : m_depth(32)
+ , m_format(QImage::Format_Invalid)
+ , m_platformContext(0)
+ , m_surface(0)
{
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglScreen %p\n", this);
@@ -116,7 +119,25 @@ QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display)
qWarning("Initialized display %d %d\n", major, minor);
- QPlatformWindowFormat platformFormat;
+ int swapInterval = 1;
+ QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL");
+ if (!swapIntervalString.isEmpty()) {
+ bool ok;
+ swapInterval = swapIntervalString.toInt(&ok);
+ if (!ok)
+ swapInterval = 1;
+ }
+ eglSwapInterval(m_dpy, swapInterval);
+}
+
+void QEglFSScreen::createAndSetPlatformContext() const {
+ const_cast<QEglFSScreen *>(this)->createAndSetPlatformContext();
+}
+
+void QEglFSScreen::createAndSetPlatformContext()
+{
+ QPlatformWindowFormat platformFormat = QPlatformWindowFormat::defaultFormat();
+
platformFormat.setWindowApi(QPlatformWindowFormat::OpenGL);
QByteArray depthString = qgetenv("QT_QPA_EGLFS_DEPTH");
@@ -132,23 +153,15 @@ QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display)
platformFormat.setRedBufferSize(8);
platformFormat.setGreenBufferSize(8);
platformFormat.setBlueBufferSize(8);
+ m_depth = 32;
+ m_format = QImage::Format_RGB32;
}
-
if (!qgetenv("QT_QPA_EGLFS_MULTISAMPLE").isEmpty()) {
platformFormat.setSampleBuffers(true);
}
- int swapInterval = 1;
- QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL");
- if (!swapIntervalString.isEmpty()) {
- bool ok;
- swapInterval = swapIntervalString.toInt(&ok);
- if (!ok)
- swapInterval = 1;
- }
EGLConfig config = q_configFromQPlatformWindowFormat(m_dpy, platformFormat);
- eglSwapInterval(display, swapInterval);
EGLNativeWindowType eglWindow = 0;
#ifdef Q_OPENKODE
@@ -189,15 +202,42 @@ QEglFSScreen::QEglFSScreen(EGLNativeDisplayType display)
attribList[temp++] = 2; // GLES version 2
attribList[temp++] = EGL_NONE;
- m_platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API, 0);
-
-// qWarning("Created platformcontext");
- EGLint w,h;
+ m_platformContext = new QEGLPlatformContext(m_dpy,config,attribList,m_surface,EGL_OPENGL_ES_API);
+ EGLint w,h; // screen size detection
eglQuerySurface(m_dpy, m_surface, EGL_WIDTH, &w);
eglQuerySurface(m_dpy, m_surface, EGL_HEIGHT, &h);
m_geometry = QRect(0,0,w,h);
+
+}
+
+QRect QEglFSScreen::geometry() const
+{
+ if (m_geometry.isNull()) {
+ createAndSetPlatformContext();
+ }
+ return m_geometry;
+}
+
+int QEglFSScreen::depth() const
+{
+ return m_depth;
+}
+
+QImage::Format QEglFSScreen::format() const
+{
+ if (m_format == QImage::Format_Invalid)
+ createAndSetPlatformContext();
+ return m_format;
+}
+QPlatformGLContext *QEglFSScreen::platformContext() const
+{
+ if (!m_platformContext) {
+ QEglFSScreen *that = const_cast<QEglFSScreen *>(this);
+ that->createAndSetPlatformContext();
+ }
+ return m_platformContext;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
index 9ed1b04..bfbfa62 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.h
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -57,13 +57,16 @@ public:
QEglFSScreen(EGLNativeDisplayType display);
~QEglFSScreen() {}
- QRect geometry() const { return m_geometry; }
- int depth() const { return m_depth; }
- QImage::Format format() const { return m_format; }
+ QRect geometry() const;
+ int depth() const;
+ QImage::Format format() const;
- QPlatformGLContext *platformContext() const { return m_platformContext; }
+ QPlatformGLContext *platformContext() const;
private:
+ void createAndSetPlatformContext() const;
+ void createAndSetPlatformContext();
+
QRect m_geometry;
int m_depth;
QImage::Format m_format;
diff --git a/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp b/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp
index fcea4d3..ebc04bd 100644
--- a/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp
+++ b/src/plugins/platforms/eglfs/qeglfswindowsurface.cpp
@@ -57,13 +57,10 @@ public:
#ifdef QEGL_EXTRA_DEBUG
qWarning("QEglPaintDevice %p, %p, %p",this, screen, widget);
#endif
- QGLFormat format;
- m_context = new QGLContext(format, widget);
- m_context->create();
}
QSize size() const { return m_screen->geometry().size(); }
- QGLContext* context() const { return m_context;}
+ QGLContext* context() const { return QGLContext::fromPlatformGLContext(m_screen->platformContext());}
QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); }
diff --git a/src/plugins/platforms/testlite/qglxintegration.cpp b/src/plugins/platforms/testlite/qglxintegration.cpp
index c35db9b..a4b7b69 100644
--- a/src/plugins/platforms/testlite/qglxintegration.cpp
+++ b/src/plugins/platforms/testlite/qglxintegration.cpp
@@ -235,8 +235,8 @@ QPlatformWindowFormat QGLXGLContext::reducePlatformWindowFormat(const QPlatformW
return retFormat;
}
-QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, QPlatformWindow *platformWindow, const QPlatformWindowFormat &format)
- : QPlatformGLContext(platformWindow)
+QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindowFormat &format)
+ : QPlatformGLContext()
, m_xd(xd)
, m_drawable((Drawable)window)
, m_context(0)
@@ -271,7 +271,7 @@ QGLXGLContext::QGLXGLContext(Window window, MyDisplay *xd, QPlatformWindow *plat
}
QGLXGLContext::QGLXGLContext(MyDisplay *display, Drawable drawable, GLXContext context)
- : QPlatformGLContext(0), m_xd(display), m_drawable(drawable), m_context(context)
+ : QPlatformGLContext(), m_xd(display), m_drawable(drawable), m_context(context)
{
}
diff --git a/src/plugins/platforms/testlite/qglxintegration.h b/src/plugins/platforms/testlite/qglxintegration.h
index 432dec5..e17790e 100644
--- a/src/plugins/platforms/testlite/qglxintegration.h
+++ b/src/plugins/platforms/testlite/qglxintegration.h
@@ -58,7 +58,7 @@ class MyDisplay;
class QGLXGLContext : public QPlatformGLContext
{
public:
- QGLXGLContext(Window window, MyDisplay *xd, QPlatformWindow *platformWindow, const QPlatformWindowFormat &format);
+ QGLXGLContext(Window window, MyDisplay *xd, const QPlatformWindowFormat &format);
~QGLXGLContext();
virtual void makeCurrent();
diff --git a/src/plugins/platforms/testlite/qtestlitewindow.cpp b/src/plugins/platforms/testlite/qtestlitewindow.cpp
index 0a6e1ff..b52aae9 100644
--- a/src/plugins/platforms/testlite/qtestlitewindow.cpp
+++ b/src/plugins/platforms/testlite/qtestlitewindow.cpp
@@ -1021,7 +1021,7 @@ QPlatformGLContext *QTestLiteWindow::glContext() const
if (!mGLContext) {
QTestLiteWindow *that = const_cast<QTestLiteWindow *>(this);
#ifndef QT_NO_OPENGL
- that->mGLContext = new QGLXGLContext(x_window, xd, that,widget()->platformWindowFormat());
+ that->mGLContext = new QGLXGLContext(x_window, xd,widget()->platformWindowFormat());
#endif
}
return mGLContext;